diff --git a/kwatchgnupg/aboutdata.cpp b/aboutdata.cpp similarity index 57% copy from kwatchgnupg/aboutdata.cpp copy to aboutdata.cpp index 68c918e9d..fb5813ec4 100644 --- a/kwatchgnupg/aboutdata.cpp +++ b/aboutdata.cpp @@ -1,73 +1,93 @@ /* aboutdata.cpp This file is part of Kleopatra, the KDE keymanager - Copyright (c) 2004 Klar�vdalens Datakonsult AB + Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB Kleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Kleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include "aboutdata.h" #include -static const char kwatchgnupg_version[] = "1.0"; -static const char description[] = I18N_NOOP("GnuPG log viewer"); +static const char kleopatra_version[] = "0.40"; +static const char description[] = I18N_NOOP("KDE Key Manager"); struct about_data { const char * name; const char * desc; const char * email; const char * web; }; static const about_data authors[] = { - { "Steffen Hansen", I18N_NOOP("Original Author"), "hansen@kde.org", 0 }, + { "Marc Mutz", I18N_NOOP("Current Maintainer"), "mutz@kde.org", 0 }, + { "Steffen Hansen", I18N_NOOP("Former Maintainer"), "hansen@kde.org", 0 }, + { "Kalle Dalheimer", I18N_NOOP("Original Author"), "kalle@kde.org", 0 }, + { "Jesper Petersen", I18N_NOOP("Original Author"), "blackie@kde.org", 0 }, }; -#if 0 -// can't create zero size array - doesn't compile + static const about_data credits[] = { - // PENDING(steffen) add stuff + { "David Faure", + I18N_NOOP("Backend configuration framework, KIO integration"), + "faure@kde.org", 0 }, + { "Michel Boyer de la Giroday", + I18N_NOOP("Key-state dependant colors and fonts in the key list"), + "michel@klaralvdalens-datakonsult.se", 0 }, + { "Daniel Molkentin", + I18N_NOOP("Certificate Wizard KIOSK integration, infrastructure"), + "molkentin@kde.org", 0 }, + { "Ralf Nolden", + I18N_NOOP("Support for obsolete EMAIL RDN in Certificate Wizard"), + "nolden@kde.org", 0 }, + { "Karl-Heinz Zimmer", + I18N_NOOP("DN display ordering support, infrastructure"), + "khz@kde.org", 0 }, }; -#endif + AboutData::AboutData() - : KAboutData( "kwatchgnupg", I18N_NOOP("KWatchGnuPG"), - kwatchgnupg_version, description, License_GPL, - "(c) 2004 Klar\xC3\xA4lvdalens Datakonsult AB\n" ) + : KAboutData( "kleopatra", I18N_NOOP("Kleopatra"), + kleopatra_version, description, License_GPL, + "(c) 2002 Steffen Hansen, Jesper Pedersen,\n" + "Kalle Dalheimer, Klar\xC3\xA4lvdalens Datakonsult AB\n\n" + "(c) 2004 Marc Mutz, Klar\xC3\xA4lvdalens Datakonsult AB" ) { using ::authors; - //using ::credits; + using ::credits; for ( unsigned int i = 0 ; i < sizeof authors / sizeof *authors ; ++i ) addAuthor( authors[i].name, authors[i].desc, authors[i].email, authors[i].web ); -#if 0 for ( unsigned int i = 0 ; i < sizeof credits / sizeof *credits ; ++i ) addCredit( credits[i].name, credits[i].desc, credits[i].email, credits[i].web ); -#endif } diff --git a/lib/kleo/cryptobackend.cpp b/aboutdata.h similarity index 57% copy from lib/kleo/cryptobackend.cpp copy to aboutdata.h index 6da71bc9e..29e516f5c 100644 --- a/lib/kleo/cryptobackend.cpp +++ b/aboutdata.h @@ -1,36 +1,43 @@ /* - kleo/cryptobackend.cpp + aboutdata.h - This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + This file is part of Kleopatra, the KDE keymanager + Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB - Libkleopatra is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. + Kleopatra is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. - Libkleopatra is distributed in the hope that it will be useful, + Kleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#include "cryptobackend.h" +#ifndef __ABOUTDATA_H__ +#define __ABOUTDATA_H__ -const char Kleo::CryptoBackend::OpenPGP[] = "OpenPGP"; -const char Kleo::CryptoBackend::SMIME[] = "SMIME"; +#include + +class AboutData : public KAboutData { +public: + AboutData(); +}; + +#endif // __ABOUTDATA_H__ diff --git a/certificateinfowidgetimpl.cpp b/certificateinfowidgetimpl.cpp index 596133819..082c035ba 100644 --- a/certificateinfowidgetimpl.cpp +++ b/certificateinfowidgetimpl.cpp @@ -1,221 +1,438 @@ -/* -*- Mode: C -*- +/* + certificateinfowidgetimpl.cpp - $Id$ + This file is part of Kleopatra, the KDE keymanager + Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB - Copyright (C) 2001 by Klarälvdalens Datakonsult AB + Kleopatra is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. - GPGMEPLUG is free software; you can redistribute it and/or modify - it under the terms of GNU General Public License as published by - the Free Software Foundation; version 2 of the License. + Kleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. - GPGMEPLUG is distributed in the hope that it will be useful, - it under the terms of GNU General Public License as published by - the Free Software Foundation; version 2 of the License - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. */ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "certificateinfowidgetimpl.h" + +// libkleopatra +#include +#include +#include + +#include + +// gpgme++ +#include + +// KDE +#include +#include +#include +#include +#include +#include + +// Qt #include #include #include #include #include #include +#include -#include -#include -#include -#include - -#include "certificateinfowidgetimpl.h" -#include "certmanager.h" +// other +#include +#include -CertificateInfoWidgetImpl::CertificateInfoWidgetImpl( CertManager* manager, bool external, - QWidget* parent, const char* name ) - : CertificateInfoWidget( parent, name ), _manager(manager), _external( external ) +CertificateInfoWidgetImpl::CertificateInfoWidgetImpl( const GpgME::Key & key, bool external, + QWidget * parent, const char * name ) + : CertificateInfoWidget( parent, name ), + mExternal( external ), + mFoundIssuer( true ), + mHaveKeyLocally( false ) { - if( !external ) importButton->setEnabled(false); - listView->setColumnWidthMode( 1, QListView::Manual ); - listView->setResizeMode( QListView::LastColumn ); + importButton->setEnabled( false ); + + listView->setColumnWidthMode( 1, QListView::Maximum ); QFontMetrics fm = fontMetrics(); listView->setColumnWidth( 1, fm.width( i18n("Information") ) * 5 ); listView->header()->setClickEnabled( false ); listView->setSorting( -1 ); connect( listView, SIGNAL( selectionChanged( QListViewItem* ) ), this, SLOT( slotShowInfo( QListViewItem* ) ) ); - pathView->setColumnWidthMode( 0, QListView::Manual ); - pathView->setResizeMode( QListView::LastColumn ); + pathView->setColumnWidthMode( 0, QListView::Maximum ); pathView->header()->hide(); connect( pathView, SIGNAL( doubleClicked( QListViewItem* ) ), this, SLOT( slotShowCertPathDetails( QListViewItem* ) ) ); connect( pathView, SIGNAL( returnPressed( QListViewItem* ) ), this, SLOT( slotShowCertPathDetails( QListViewItem* ) ) ); connect( importButton, SIGNAL( clicked() ), this, SLOT( slotImportCertificate() ) ); + + dumpView->setFont( KGlobalSettings::fixedFont() ); + + if ( !key.isNull() ) + setKey( key ); } -void CertificateInfoWidgetImpl::setCert( const CryptPlugWrapper::CertificateInfo& info ) -{ +static QString time_t2string( time_t t ) { + QDateTime dt; + dt.setTime_t( t ); + return dt.toString(); +} + +void CertificateInfoWidgetImpl::setKey( const GpgME::Key & key ) { + mChain.clear(); + mFoundIssuer = true; + mHaveKeyLocally = false; + listView->clear(); pathView->clear(); - _info = info; + importButton->setEnabled( false ); - /* Check if we already have the cert in question */ - if( _manager ) { - importButton->setEnabled( !_manager->haveCertificate( info.fingerprint ) ); - } else { - importButton->setEnabled( false ); + if ( key.isNull() ) + return; + + mChain.push_front( key ); + startKeyExistanceCheck(); // starts a local keylisting to enable the + // importButton if needed + + QListViewItem * item = 0; + item = new QListViewItem( listView, item, i18n("Valid"), QString("From %1 to %2") + .arg( time_t2string( key.subkey(0).creationTime() ), + time_t2string( key.subkey(0).expirationTime() ) ) ); + item = new QListViewItem( listView, item, i18n("Can be used for signing"), + key.canSign() ? i18n("Yes") : i18n("No") ); + item = new QListViewItem( listView, item, i18n("Can be used for encryption"), + key.canEncrypt() ? i18n("Yes") : i18n("No") ); + item = new QListViewItem( listView, item, i18n("Can be used for certification"), + key.canCertify() ? i18n("Yes") : i18n("No") ); + item = new QListViewItem( listView, item, i18n("Can be used for authentication"), + key.canAuthenticate() ? i18n("Yes") : i18n("No" ) ); + item = new QListViewItem( listView, item, i18n("Fingerprint"), key.primaryFingerprint() ); + item = new QListViewItem( listView, item, i18n("Issuer"), Kleo::DN( key.issuerName() ).prettyDN() ); + item = new QListViewItem( listView, item, i18n("Serial Number"), key.issuerSerial() ); + + const Kleo::DN dn = key.userID(0).id(); + + // FIXME: use the attributeLabelMap from certificatewizardimpl.cpp: + static QMap dnComponentNames; + if ( dnComponentNames.isEmpty() ) { + dnComponentNames["C"] = i18n("Country"); + dnComponentNames["OU"] = i18n("Organizational Unit"); + dnComponentNames["O"] = i18n("Organization"); + dnComponentNames["L"] = i18n("Location"); + dnComponentNames["CN"] = i18n("Common Name"); + dnComponentNames["EMAIL"] = i18n("Email"); } - // These will show in the opposite order - // disabled until supported - //new QListViewItem( listView, i18n("CRL Dist. Point"), info.crl ); - new QListViewItem( listView, i18n("Fingerprint"), info.fingerprint ); - new QListViewItem( listView, i18n("Can be used for certification"), - info.certify?i18n("Yes"):i18n("No") ); - new QListViewItem( listView, i18n("Can be used for encryption"), - info.encrypt?i18n("Yes"):i18n("No") ); - new QListViewItem( listView, i18n("Can be used for signing"), - info.sign?i18n("Yes"):i18n("No") ); - - new QListViewItem( listView, i18n("Valid"), QString("From %1 to %2") - .arg( info.created.toString() ).arg(info.expire.toString()) ); - - - //new QListViewItem( listView, i18n("Email"), info.dn["1.2.840.113549.1.9.1"] ); - new QListViewItem( listView, i18n("Country"), info.dn["C"] ); - new QListViewItem( listView, i18n("Organizational Unit"), info.dn["OU"] ); - new QListViewItem( listView, i18n("Organization"), info.dn["O"] ); - new QListViewItem( listView, i18n("Location"), info.dn["L"] ); - new QListViewItem( listView, i18n("Serial Number"), info.serial ); - new QListViewItem( listView, i18n("Name"), info.dn["CN"] ); - new QListViewItem( listView, i18n("Issuer"), info.issuer.stripWhiteSpace() ); - - QStringList::ConstIterator it = info.userid.begin(); - QListViewItem* item = new QListViewItem( listView, i18n("Subject"), - (*it).stripWhiteSpace() ); - ++it; - while( it != info.userid.end() ) { - if( (*it)[0] == '<' ) { - item = new QListViewItem( listView, item, i18n("Email"), (*it).mid(1,(*it).length()-2)); - } else { - item = new QListViewItem( listView, item, i18n("Aka"), (*it).stripWhiteSpace() ); - } - ++it; - } - - // Set up cert. path - if( !_manager ) return; - const CryptPlugWrapper::CertificateInfoList& lst = _manager->certList(); - QString issuer = info.issuer; - QStringList items; - items << info.userid[0]; - bool root_found = false; - while( true ) { - bool found = false; - CryptPlugWrapper::CertificateInfo info; - for( CryptPlugWrapper::CertificateInfoList::ConstIterator it = lst.begin(); - it != lst.end(); ++it ) { - if( (*it).userid[0] == issuer && !items.contains( info.userid[0] ) ) { - info = (*it); - found = true; - break; - } + + for ( Kleo::DN::const_iterator dnit = dn.begin() ; dnit != dn.end() ; ++dnit ) { + QString displayName = (*dnit).name(); + if( dnComponentNames.contains(displayName) ) displayName = dnComponentNames[displayName]; + item = new QListViewItem( listView, item, displayName, (*dnit).value() ); + } + + const std::vector uids = key.userIDs(); + if ( !uids.empty() ) { + item = new QListViewItem( listView, item, i18n("Subject"), + Kleo::DN( uids.front().id() ).prettyDN() ); + for ( std::vector::const_iterator it = uids.begin() + 1 ; it != uids.end() ; ++it ) { + if ( !(*it).id() ) + continue; + const QString email = QString::fromUtf8( (*it).id() ).stripWhiteSpace(); + if ( email.isEmpty() ) + continue; + if ( email.startsWith( "<" ) ) + item = new QListViewItem( listView, item, i18n("Email"), + email.mid( 1, email.length()-2 ) ); + else + item = new QListViewItem( listView, item, i18n("A.k.a."), email ); } - if( found ) { - items.prepend( info.userid[0] ); - issuer = info.issuer; - // FIXME(steffen): Use real DN comparison - if( info.userid[0] == info.issuer ) { - // Root item - root_found = true; - break; - } - } else break; } - item = 0; - if( !root_found ) { - if( items.count() > 0 ) items.prepend( QString::fromUtf8("Root certificate not found (%1)").arg( issuer ) ); - else items.prepend( "Root certificate not found" ); + + updateChainView(); + startCertificateChainListing(); + startCertificateDump(); +} + +static void showChainListError( QWidget * parent, const GpgME::Error & err, const char * subject ) { + assert( err ); + const QString msg = i18n("

An error occurred while fetching " + "the certificate %1 from the backend:

" + "

%2

") + .arg( subject ? QString::fromUtf8( subject ) : QString::null, + QString::fromLocal8Bit( err.asString() ) ); + KMessageBox::error( parent, msg, i18n("Certificate Listing Failed" ) ); +} + +void CertificateInfoWidgetImpl::startCertificateChainListing() { + kdDebug() << "CertificateInfoWidgetImpl::startCertificateChainListing()" << endl; + + if ( mChain.empty() ) { + // we need a seed... + kdWarning() << "CertificateInfoWidgetImpl::startCertificateChainListing(): mChain is empty!" << endl; + return; } - for( QStringList::Iterator it = items.begin(); it != items.end(); ++it ) { - if( item ) item = new QListViewItem( item, (*it) ); - else item = new QListViewItem( pathView, (*it) ); - item->setOpen( true ); + const char * chainID = mChain.front().chainID(); + if ( !chainID || !*chainID ) { + // cert not found: + kdDebug() << "CertificateInfoWidgetImpl::startCertificateChainListing(): empty chain ID - root not found" << endl; + return; + } + const char * fpr = mChain.front().primaryFingerprint(); + if ( qstricmp( fpr, chainID ) == 0 ) { + kdDebug() << "CertificateInfoWidgetImpl::startCertificateChainListing(): chain_id equals fingerprint -> found root" << endl; + return; + } + if ( mChain.size() > 100 ) { + // safe guard against certificate loops (paranoia factor 8 out of 10)... + kdWarning() << "CertificateInfoWidgetImpl::startCertificateChainListing(): maximum chain length of 100 exceeded!" << endl; + return; + } + if ( !mFoundIssuer ) { + // key listing failed. Don't end up in endless loop + kdDebug() << "CertificateInfoWidgetImpl::startCertificateChainListing(): issuer not found - giving up" << endl; + return; + } + + mFoundIssuer = false; + + // gpgsm / dirmngr / LDAP / whoever doesn't support looking up + // external keys by fingerprint. Furthermore, since we actually got + // a chain-id set on the key, we know that we have the issuer's cert + // in the local keyring, so just use local keylisting. + Kleo::KeyListJob * job = + Kleo::CryptoBackendFactory::instance()->smime()->keyListJob( false ); + assert( job ); + + connect( job, SIGNAL(result(const GpgME::KeyListResult&)), + SLOT(slotCertificateChainListingResult(const GpgME::KeyListResult&)) ); + connect( job, SIGNAL(nextKey(const GpgME::Key&)), + SLOT(slotNextKey(const GpgME::Key&)) ); + + kdDebug() << "Going to fetch" << endl + << " issuer : \"" << mChain.front().issuerName() << "\"" << endl + << " chain id: " << mChain.front().chainID() << endl + << "for" << endl + << " subject : \"" << mChain.front().userID(0).id() << "\"" << endl + << " subj.fpr: " << mChain.front().primaryFingerprint() << endl; + + const GpgME::Error err = job->start( mChain.front().chainID() ); + + if ( err ) + showChainListError( this, err, mChain.front().issuerName() ); + else + (void)new Kleo::ProgressDialog( job, i18n("Fetching Certificate Chain"), this ); +} + +void CertificateInfoWidgetImpl::startCertificateDump() { + KProcess* proc = new KProcess( this ); + (*proc) << "gpgsm"; // must be in the PATH + (*proc) << "--dump-keys"; + (*proc) << mChain.front().primaryFingerprint(); + + QObject::connect( proc, SIGNAL( receivedStdout(KProcess *, char *, int) ), + this, SLOT( slotCollectStdout(KProcess *, char *, int) ) ); + QObject::connect( proc, SIGNAL( receivedStderr(KProcess *, char *, int) ), + this, SLOT( slotCollectStderr(KProcess *, char *, int) ) ); + QObject::connect( proc, SIGNAL( processExited(KProcess*) ), + this, SLOT( slotDumpProcessExited(KProcess*) ) ); + + if ( !proc->start( KProcess::NotifyOnExit, (KProcess::Communication)(KProcess::Stdout | KProcess::Stderr) ) ) { + QString wmsg = i18n("Failed to execute gpgsm:\n%1").arg( i18n( "program not found" ) ); + dumpView->setText( wmsg ); } } -void CertificateInfoWidgetImpl::slotShowInfo( QListViewItem* item ) +void CertificateInfoWidgetImpl::slotCollectStdout(KProcess *, char *buffer, int buflen) { - textView->setText( item->text(1) ); + mDumpOutput += QCString(buffer, buflen+1); // like KProcIO does } -void CertificateInfoWidgetImpl::slotShowCertPathDetails( QListViewItem* item ) +void CertificateInfoWidgetImpl::slotCollectStderr(KProcess *, char *buffer, int buflen) { - if( !_manager ) return; - const CryptPlugWrapper::CertificateInfoList& lst = _manager->certList(); - for( CryptPlugWrapper::CertificateInfoList::ConstIterator it = lst.begin(); - it != lst.end(); ++it ) { - if( (*it).userid[0] == item->text(0) ) { - KDialogBase* dialog = new KDialogBase( this, "dialog", true, i18n("Additional Information for Key"), KDialogBase::Close, KDialogBase::Close ); - - CertificateInfoWidgetImpl* top = new CertificateInfoWidgetImpl( _manager, _manager->isRemote(), dialog ); - dialog->setMainWidget( top ); - top->setCert( *it ); - dialog->exec(); - delete dialog; + mDumpError += QCString(buffer, buflen+1); // like KProcIO does +} + +void CertificateInfoWidgetImpl::slotDumpProcessExited(KProcess* proc) { + int rc = ( proc->normalExit() ) ? proc->exitStatus() : -1 ; + + if ( rc == 0 ) { + dumpView->setText( QString::fromUtf8( mDumpOutput ) ); + } else { + if ( !mDumpError.isEmpty() ) { + dumpView->setText( QString::fromUtf8( mDumpError ) ); + } else + { + QString wmsg = i18n("Failed to execute gpgsm:\n%1"); + if ( rc == -1 ) + wmsg = wmsg.arg( i18n( "program cannot be executed" ) ); + else + wmsg = wmsg.arg( strerror(rc) ); + dumpView->setText( wmsg ); } } + + proc->deleteLater(); } +void CertificateInfoWidgetImpl::slotNextKey( const GpgME::Key & key ) { + kdDebug() << "CertificateInfoWidgetImpl::slotNextKey( \"" + << key.userID(0).id() << "\" )" << endl; + if ( key.isNull() ) + return; -static QString parseXMLInfo( const QString& info ) -{ - QString result; - QDomDocument doc; - if( !doc.setContent( info ) ) { - kdDebug() << "xml parser error in CertificateInfoWidgetImpl::slotImportCertificate()" << endl; + mFoundIssuer = true; + mChain.push_front( key ); + updateChainView(); + // FIXME: cancel the keylisting. We're only interested in _one_ key. +} + +void CertificateInfoWidgetImpl::updateChainView() { + pathView->clear(); + if ( mChain.empty() ) + return; + QListViewItem * item = 0; + + QValueList::const_iterator it = mChain.begin(); + // root item: + if ( (*it).chainID() && qstrcmp( (*it).chainID(), (*it).primaryFingerprint() ) == 0 ) + item = new QListViewItem( pathView, Kleo::DN( (*it++).userID(0).id() ).prettyDN() ); + else { + item = new QListViewItem( pathView, i18n("Issuer certificate not found ( %1)") + .arg( Kleo::DN( (*it).issuerName() ).prettyDN() ) ); + item->setOpen( true ); // Qt bug: doesn't open after setEnabled( false ) :/ + item->setEnabled( false ); } - QDomNode importinfo = doc.documentElement().namedItem("importResult"); - result = i18n("

"); - for( QDomNode n = importinfo.firstChild(); !n.isNull(); n = n.nextSibling() ) { - if( n.isElement() ) { - QDomElement elem = n.toElement(); - if( elem.tagName() == "count" || elem.text().toInt() != 0 ) { - result += ""; - } - } + item->setOpen( true ); + + // subsequent items: + while ( it != mChain.end() ) { + item = new QListViewItem( item, Kleo::DN( (*it++).userID(0).id() ).prettyDN() ); + item->setOpen( true ); } - result += "
NameValue
"+ elem.tagName() + "" - + elem.text().stripWhiteSpace() + "

"; - return result; } +void CertificateInfoWidgetImpl::slotCertificateChainListingResult( const GpgME::KeyListResult & res ) { + if ( res.error() ) + return showChainListError( this, res.error(), mChain.front().issuerName() ); + else + startCertificateChainListing(); +} + +void CertificateInfoWidgetImpl::slotShowInfo( QListViewItem * item ) { + textView->setText( item->text(1) ); +} + +void CertificateInfoWidgetImpl::slotShowCertPathDetails( QListViewItem * item ) { + if ( !item ) + return; + + // find the key corresponding to "item". This hack would not be + // necessary if pathView was a Kleo::KeyListView, but it's + // Qt-Designer-generated and I don't feel like creating a custom + // widget spec for Kleo::KeyListView. + unsigned int totalCount = 0; + int itemIndex = -1; + for ( const QListViewItem * i = pathView->firstChild() ; i ; i = i->firstChild() ) { + if ( i == item ) + itemIndex = totalCount; + ++totalCount; + } + + assert( totalCount == mChain.size() || totalCount == mChain.size() + 1 ); + + // skip pseudo root item with "not found message": + if ( totalCount == mChain.size() + 1 ) + --itemIndex; + + assert( itemIndex >= 0 ); + + KDialogBase * dialog = + new KDialogBase( this, "dialog", false, i18n("Additional Information for Key"), + KDialogBase::Close, KDialogBase::Close ); + CertificateInfoWidgetImpl * top = + new CertificateInfoWidgetImpl( mChain[itemIndex], mExternal, dialog ); + dialog->setMainWidget( top ); + // proxy the signal to our receiver: + connect( top, SIGNAL(requestCertificateDownload(const QString&, const QString&)), + SIGNAL(requestCertificateDownload(const QString&, const QString&)) ); + dialog->show(); +} + + void CertificateInfoWidgetImpl::slotImportCertificate() { - if( !_manager ) return; - QApplication::setOverrideCursor( QCursor::WaitCursor ); - QString info; - int retval = _manager->importCertificateWithFingerprint( _info.fingerprint, &info ); - info = parseXMLInfo( info ); - - QApplication::restoreOverrideCursor(); - - if( retval == -42 ) { - KMessageBox::error( this, i18n("CryptPlug returned success, but no certificate was imported.
You may need to import the issuer certificate %1 first.
Additional info:
%2
").arg( _info.issuer ).arg(info), - i18n("Import Error") ); - } else if( retval ) { - KMessageBox::error( this, i18n("Error importing certificate.
CryptPlug returned %1. Additional info:
%2
").arg(retval).arg( info ), i18n("Import Error") ); - } else { - KMessageBox::information( this, i18n("Certificate %1 with fingerprint %2 is imported to the local database.
Additional info:
%3
").arg(_info.userid[0]).arg(_info.fingerprint).arg( info ), i18n("Certificate Imported") ); - importButton->setEnabled( false ); - } + if ( mChain.empty() || mChain.back().isNull() ) + return; + const Kleo::DN dn = mChain.back().userID( 0 ).id(); + emit requestCertificateDownload( mChain.back().primaryFingerprint(), dn.prettyDN() ); + importButton->setEnabled( false ); } + +void CertificateInfoWidgetImpl::startKeyExistanceCheck() { + if ( !mExternal ) + // we already have it if it's from a local keylisting :) + return; + if ( mChain.empty() || mChain.back().isNull() ) + // need a key to look for + return; + const QString fingerprint = mChain.back().primaryFingerprint(); + if ( fingerprint.isEmpty() ) + // empty pattern means list all keys. We don't want that + return; + + // start _local_ keylistjob (no progressdialog needed here): + Kleo::KeyListJob * job = + Kleo::CryptoBackendFactory::instance()->smime()->keyListJob( false ); + assert( job ); + + connect( job, SIGNAL(nextKey(const GpgME::Key&)), + SLOT(slotKeyExistanceCheckNextCandidate(const GpgME::Key&)) ); + connect( job, SIGNAL(result(const GpgME::KeyListResult&)), + SLOT(slotKeyExistanceCheckFinished()) ); + // nor to check for errors: + job->start( fingerprint ); +} + +void CertificateInfoWidgetImpl::slotKeyExistanceCheckNextCandidate( const GpgME::Key & key ) { + if ( key.isNull() || mChain.empty() || !key.primaryFingerprint() ) + return; + + if ( qstrcmp( key.primaryFingerprint(), + mChain.back().primaryFingerprint() ) == 0 ) + mHaveKeyLocally = true; +} + +void CertificateInfoWidgetImpl::slotKeyExistanceCheckFinished() { + importButton->setEnabled( !mHaveKeyLocally ); +} + + #include "certificateinfowidgetimpl.moc" diff --git a/certificateinfowidgetimpl.h b/certificateinfowidgetimpl.h index 26df7fc1c..961d67c39 100644 --- a/certificateinfowidgetimpl.h +++ b/certificateinfowidgetimpl.h @@ -1,49 +1,87 @@ -/* -*- Mode: C -*- +/* + certificateinfowidgetimpl.h - $Id$ + This file is part of Kleopatra, the KDE keymanager + Copyright (c) 2001,2004 Klarälvdalens Datakonsult AB - Copyright (C) 2001 by Klarälvdalens Datakonsult AB + Kleopatra is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. - GPGMEPLUG is free software; you can redistribute it and/or modify - it under the terms of GNU General Public License as published by - the Free Software Foundation; version 2 of the License. + Kleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. - GPGMEPLUG is distributed in the hope that it will be useful, - it under the terms of GNU General Public License as published by - the Free Software Foundation; version 2 of the License - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. */ #ifndef CERTIFICATEINFOWIDGETIMPL_H #define CERTIFICATEINFOWIDGETIMPL_H #include "certificateinfowidget.h" -#include +#include + +#include + +class KProcess; class QListViewItem; -class CertManager; + +namespace GpgME { + class KeyListResult; +} class CertificateInfoWidgetImpl : public CertificateInfoWidget { Q_OBJECT public: - CertificateInfoWidgetImpl( CertManager* manager, bool external, - QWidget* parent = 0, const char* name = 0); + CertificateInfoWidgetImpl( const GpgME::Key & key, bool external, + QWidget * parent=0, const char * name=0); + + void setKey( const GpgME::Key & key ); - void setCert( const CryptPlugWrapper::CertificateInfo& info ); -protected slots: +signals: + void requestCertificateDownload( const QString & fingerprint, const QString& displayName ); + +private slots: void slotShowInfo( QListViewItem* ); - void slotShowCertPathDetails( QListViewItem* ); + void slotShowCertPathDetails( QListViewItem* ); void slotImportCertificate(); + void slotCertificateChainListingResult( const GpgME::KeyListResult & res ); + void slotNextKey( const GpgME::Key & key ); + void slotKeyExistanceCheckNextCandidate( const GpgME::Key & key ); + void slotKeyExistanceCheckFinished(); + void slotCollectStdout(KProcess *, char *, int); + void slotCollectStderr(KProcess *, char *, int); + void slotDumpProcessExited(KProcess*); + +private: + void startCertificateChainListing(); + void startCertificateDump(); + void startKeyExistanceCheck(); + void updateChainView(); + private: - CertManager* _manager; - CryptPlugWrapper::CertificateInfo _info; - bool _external; + QCString mDumpOutput; + QCString mDumpError; + QValueList mChain; + bool mExternal; + bool mFoundIssuer; + bool mHaveKeyLocally; }; #endif // CERTIFICATEINFOWIDGETIMPL_H diff --git a/certificatewizardimpl.cpp b/certificatewizardimpl.cpp index 24f41276f..8c2d6a8ac 100644 --- a/certificatewizardimpl.cpp +++ b/certificatewizardimpl.cpp @@ -1,515 +1,515 @@ /* certificatewizardimpl.cpp This file is part of Kleopatra, the KDE keymanager Copyright (c) 2001,2002,2004 Klar�vdalens Datakonsult AB Kleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Kleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifdef HAVE_CONFIG_H #include #endif #include "certificatewizardimpl.h" #include "storedtransferjob.h" // libkleopatra #include #include #include #include #include // gpgme++ #include // KDE #include #include #include #include #include #include #include #include #include #include #include #include // Qt #include #include #include #include #include #include #include #include #include #include static const unsigned int keyLengths[] = { 1024, 1532, 2048, 3072, 4096 }; static const unsigned int numKeyLengths = sizeof keyLengths / sizeof *keyLengths; static QString attributeLabel( const QString & attr, bool required ) { if ( attr.isEmpty() ) return QString::null; const QString label = Kleo::DNAttributeMapper::instance()->name2label( attr ); if ( !label.isEmpty() ) if ( required ) return i18n("Format string for the labels in the \"Your Personal Data\" page - required field", "*%1 (%2):").arg( label, attr ); else return i18n("Format string for the labels in the \"Your Personal Data\" page", "%1 (%2):").arg( label, attr ); else if ( required ) return '*' + attr + ':'; else return attr + ':'; } static QString attributeFromKey( QString key ) { return key.remove( '!' ); } static bool availForMod( const QLineEdit * le ) { return le && le->isEnabled(); } /* * Constructs a CertificateWizardImpl which is a child of 'parent', with the * name 'name' and widget flags set to 'f' * * The wizard will by default be modeless, unless you set 'modal' to * TRUE to construct a modal wizard. */ CertificateWizardImpl::CertificateWizardImpl( QWidget* parent, const char* name, bool modal, WFlags fl ) : CertificateWizard( parent, name, modal, fl ) { // don't allow to go to last page until a key has been generated setNextEnabled( generatePage, false ); // setNextEnabled( personalDataPage, false ); // ## disable again once we have a criteria when to enable again createPersonalDataPage(); // Allow to select remote URLs storeUR->setMode( KFile::File ); storeUR->setFilter( "application/pkcs10" ); connect( storeUR, SIGNAL( urlSelected( const QString& ) ), this, SLOT( slotURLSelected( const QString& ) ) ); const KConfigGroup config( KGlobal::config(), "CertificateCreationWizard" ); caEmailED->setText( config.readEntry( "CAEmailAddress" ) ); connect( this, SIGNAL( helpClicked() ), this, SLOT( slotHelpClicked() ) ); connect( insertAddressButton, SIGNAL( clicked() ), this, SLOT( slotSetValuesFromWhoAmI() ) ); for ( unsigned int i = 0 ; i < numKeyLengths ; ++i ) keyLengthCB->insertItem( i18n("%n bit", "%n bits", keyLengths[i] ) ); } static bool requirementsAreMet( const CertificateWizardImpl::AttrPairList & list ) { for ( CertificateWizardImpl::AttrPairList::const_iterator it = list.begin() ; it != list.end() ; ++it ) { const QLineEdit * le = (*it).second; if ( !le ) continue; const QString key = (*it).first; #ifndef NDEBUG kdbgstream s = kdDebug(); #else kndbgstream s = kdDebug(); #endif s << "requirementsAreMet(): checking \"" << key << "\" against \"" << le->text() << "\": "; if ( key.endsWith("!") && le->text().stripWhiteSpace().isEmpty() ) { s << "required field is empty!" << endl; return false; } s << "ok" << endl; } return true; } /* This slot is called when the user changes the text. */ void CertificateWizardImpl::slotEnablePersonalDataPageExit() { setNextEnabled( personalDataPage, requirementsAreMet( _attrPairList ) ); } /* * Destroys the object and frees any allocated resources */ CertificateWizardImpl::~CertificateWizardImpl() { // no need to delete child widgets, Qt does it all for us } static const char * oidForAttributeName( const QString & attr ) { QCString attrUtf8 = attr.utf8(); for ( unsigned int i = 0 ; i < numOidMaps ; ++i ) if ( qstricmp( attrUtf8, oidmap[i].name ) == 0 ) return oidmap[i].oid; return 0; } /* * protected slot */ void CertificateWizardImpl::slotGenerateCertificate() { // Ask gpgme to generate a key and return it QString certParms; certParms += "\n"; certParms += "Key-Type: RSA\n"; certParms += QString( "Key-Length: %1\n" ).arg( keyLengths[keyLengthCB->currentItem()] ); certParms += "Key-Usage: "; if ( signOnlyCB->isChecked() ) certParms += "Sign"; else if ( encryptOnlyCB->isChecked() ) certParms += "Encrypt"; else certParms += "Sign, Encrypt"; certParms += "\n"; certParms += "name-dn: "; QString email; QStringList rdns; for( AttrPairList::const_iterator it = _attrPairList.begin(); it != _attrPairList.end(); ++it ) { const QString attr = attributeFromKey( (*it).first.upper() ); const QLineEdit * le = (*it).second; if ( !le ) continue; const QString value = le->text().stripWhiteSpace(); if ( value.isEmpty() ) continue; if ( attr == "EMAIL" ) { // EMAIL is special, since it shouldn't be part of the DN, // except for non-RFC-conformant CAs that require it to be // there. email = value; if ( !brokenCA->isChecked() ) continue; } if ( const char * oid = oidForAttributeName( attr ) ) { // we need to translate the attribute name for the backend: rdns.push_back( QString::fromUtf8( oid ) + '=' + value ); } else { rdns.push_back( attr + '=' + value ); } } certParms += rdns.join(","); if( !email.isEmpty() ) certParms += "\nname-email: " + email; certParms += "\n\n"; kdDebug() << certParms << endl; Kleo::KeyGenerationJob * job = Kleo::CryptoBackendFactory::instance()->smime()->keyGenerationJob(); assert( job ); connect( job, SIGNAL(result(const GpgME::KeyGenerationResult&,const QByteArray&)), SLOT(slotResult(const GpgME::KeyGenerationResult&,const QByteArray&)) ); certificateTE->setText( certParms ); const GpgME::Error err = job->start( certParms ); if ( err ) KMessageBox::error( this, i18n( "Could not start certificate generation: %1" ) .arg( QString::fromLocal8Bit( err.asString() ) ), i18n( "Certificate Manager Error" ) ); else { generatePB->setEnabled( false ); setBackEnabled( generatePage, false ); (void)new Kleo::ProgressDialog( job, i18n("Generating key"), this ); } } void CertificateWizardImpl::slotResult( const GpgME::KeyGenerationResult & res, const QByteArray & keyData ) { //kdDebug() << "keyData.size(): " << keyData.size() << endl; _keyData = keyData; if ( res.error().isCanceled() || res.error() ) { setNextEnabled( generatePage, false ); setBackEnabled( generatePage, true ); setFinishEnabled( finishPage, false ); generatePB->setEnabled( true ); if ( !res.error().isCanceled() ) KMessageBox::error( this, i18n( "Could not generate certificate: %1" ) .arg( QString::fromLatin1( res.error().asString() ) ), i18n( "Certificate Manager Error" ) ); } else { // next will stay enabled until the user clicks Generate // Certificate again setNextEnabled( generatePage, true ); setFinishEnabled( finishPage, true ); } } void CertificateWizardImpl::slotHelpClicked() { kapp->invokeHelp( "newcert" ); } void CertificateWizardImpl::slotSetValuesFromWhoAmI() { const KABC::Addressee a = KABC::StdAddressBook::self( true )->whoAmI(); if ( a.isEmpty() ) return; const KABC::Address adr = a.address(KABC::Address::Work); for ( AttrPairList::const_iterator it = _attrPairList.begin() ; it != _attrPairList.end() ; ++it ) { QLineEdit * le = (*it).second; if ( !availForMod( le ) ) continue; const QString attr = attributeFromKey( (*it).first.upper() ); if ( attr == "CN" ) le->setText( a.formattedName() ); else if ( attr == "EMAIL" ) le->setText( a.preferredEmail() ); else if ( attr == "O" ) le->setText( a.organization() ); else if ( attr == "OU" ) le->setText( a.custom( "KADDRESSBOOK", "X-Department" ) ); else if ( attr == "L" ) le->setText( adr.locality() ); else if ( attr == "SP" ) le->setText( adr.region() ); else if ( attr == "PC" ) le->setText( adr.postalCode() ); else if ( attr == "SN" ) le->setText( a.familyName() ); else if ( attr == "GN" ) le->setText( a.givenName() ); else if ( attr == "T" ) le->setText( a.title() ); else if ( attr == "BC" ) le->setText( a.role() ); // correct mapping? } } void CertificateWizardImpl::createPersonalDataPage() { QGridLayout* grid = new QGridLayout( edContainer, 2, 1, KDialog::marginHint(), KDialog::spacingHint() ); KConfigGroup config( KGlobal::config(), "CertificateCreationWizard" ); QStringList attrOrder = config.readListEntry( "DNAttributeOrder" ); if ( attrOrder.empty() ) attrOrder << "CN!" << "L" << "OU" << "O!" << "C!" << "EMAIL!"; int row = 0; for ( QStringList::const_iterator it = attrOrder.begin() ; it != attrOrder.end() ; ++it, ++row ) { const QString key = (*it).stripWhiteSpace().upper(); const QString attr = attributeFromKey( key ); if ( attr.isEmpty() ) { --row; continue; } const QString preset = config.readEntry( attr ); const QString label = config.readEntry( attr + "_label", attributeLabel( attr, key.endsWith("!") ) ); QLineEdit * le = new QLineEdit( edContainer ); grid->addWidget( le, row, 1 ); grid->addWidget( new QLabel( le, label.isEmpty() ? attr : label, edContainer ), row, 0 ); le->setText( preset ); if ( config.entryIsImmutable( attr ) ) le->setEnabled( false ); _attrPairList.append(qMakePair(key, le)); connect( le, SIGNAL(textChanged(const QString&)), SLOT(slotEnablePersonalDataPageExit()) ); } // enable button only if administrator wants to allow it if (KABC::StdAddressBook::self( true )->whoAmI().isEmpty() || !config.readBoolEntry("ShowSetWhoAmI", true)) insertAddressButton->setEnabled( false ); slotEnablePersonalDataPageExit(); } bool CertificateWizardImpl::sendToCA() const { return sendToCARB->isChecked(); } QString CertificateWizardImpl::caEMailAddress() const { return caEmailED->text().stripWhiteSpace(); } void CertificateWizardImpl::slotURLSelected( const QString& _url ) { KURL url = KURL::fromPathOrURL( _url.stripWhiteSpace() ); #if ! KDE_IS_VERSION(3,2,90) // The application/pkcs10 mimetype didn't have a native extension, // so the filedialog didn't have the checkbox for auto-adding it. QString fileName = url.fileName(); int pos = fileName.findRev( '.' ); if ( pos < 0 ) // no extension url.setFileName( fileName + ".p10" ); #endif storeUR->setURL( url.prettyURL() ); } KURL CertificateWizardImpl::saveFileUrl() const { return KURL::fromPathOrURL( storeUR->url().stripWhiteSpace() ); } void CertificateWizardImpl::showPage( QWidget * page ) { CertificateWizard::showPage( page ); if ( page == generatePage ) { // Initial settings for the generation page: focus the correct lineedit // and disable the other one if ( storeInFileRB->isChecked() ) { storeUR->setEnabled( true ); caEmailED->setEnabled( false ); storeUR->setFocus(); } else { storeUR->setEnabled( false ); caEmailED->setEnabled( true ); caEmailED->setFocus(); } } } static const char* const dcopObjectId = "KMailIface"; /** Send the new certificate by mail using KMail */ void CertificateWizardImpl::sendCertificate( const QString& email, const QByteArray& certificateData ) { QString error; QCString dcopService; int result = KDCOPServiceStarter::self()-> findServiceFor( "DCOP/Mailer", QString::null, QString::null, &error, &dcopService ); if ( result != 0 ) { kdDebug() << "Couldn't connect to KMail\n"; KMessageBox::error( this, i18n( "DCOP Communication Error, unable to send certificate using KMail.\n%1" ).arg( error ) ); return; } QCString dummy; // OK, so kmail (or kontact) is running. Now ensure the object we want is available. // [that's not the case when kontact was already running, but kmail not loaded into it... in theory.] if ( !kapp->dcopClient()->findObject( dcopService, dcopObjectId, "", QByteArray(), dummy, dummy ) ) { DCOPRef ref( dcopService, dcopService ); // talk to the KUniqueApplication or its kontact wrapper DCOPReply reply = ref.call( "load()" ); if ( reply.isValid() && (bool)reply ) { Q_ASSERT( kapp->dcopClient()->findObject( dcopService, dcopObjectId, "", QByteArray(), dummy, dummy ) ); } else kdWarning() << "Error loading " << dcopService << endl; } DCOPClient* dcopClient = kapp->dcopClient(); QByteArray data; QDataStream arg( data, IO_WriteOnly ); arg << email; arg << certificateData; if( !dcopClient->send( dcopService, dcopObjectId, "sendCertificate(QString,QByteArray)", data ) ) { KMessageBox::error( this, i18n( "DCOP Communication Error, unable to send certificate using KMail." ) ); return; } // All good, close dialog CertificateWizard::accept(); } // Called when pressing Finish // We want to do the emailing/uploading first, before closing the dialog, // in case of errors during the upload. void CertificateWizardImpl::accept() { if( sendToCA() ) { // Ask KMail to send this key to the CA. sendCertificate( caEMailAddress(), _keyData ); } else { // Save in file/URL KURL url = saveFileUrl(); bool overwrite = false; if ( KIO::NetAccess::exists( url, false /*dest*/, this ) ) { if ( KMessageBox::Cancel == KMessageBox::warningContinueCancel( this, i18n( "A file named \"%1\" already exists. " "Are you sure you want to overwrite it?" ).arg( url.prettyURL() ), i18n( "Overwrite File?" ), i18n( "&Overwrite" ) ) ) return; overwrite = true; } KIO::Job* uploadJob = KIOext::put( _keyData, url, -1, overwrite, false /*resume*/ ); uploadJob->setWindow( this ); connect( uploadJob, SIGNAL( result( KIO::Job* ) ), this, SLOT( slotUploadResult( KIO::Job* ) ) ); // Can't press finish again during the upload setFinishEnabled( finishPage, false ); } } /** This slot is invoked by the KIO job used in newCertificate to save/upload the certificate, when finished (success or error). */ void CertificateWizardImpl::slotUploadResult( KIO::Job* job ) { if ( job->error() ) { job->showErrorDialog(); setFinishEnabled( finishPage, true ); } else { // All good, close dialog CertificateWizard::accept(); } } #include "certificatewizardimpl.moc" diff --git a/certificatewizardimpl.h b/certificatewizardimpl.h index bbd49673d..d275cbc72 100644 --- a/certificatewizardimpl.h +++ b/certificatewizardimpl.h @@ -1,27 +1,88 @@ +/* + certificatewizardimpl.h + + This file is part of Kleopatra, the KDE keymanager + Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB + + Kleopatra is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + Kleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + #ifndef CERTIFICATEWIZARDIMPL_H #define CERTIFICATEWIZARDIMPL_H #include "certificatewizard.h" #include +#include +#include +#include + +namespace GpgME { + class KeyGenerationResult; +} +namespace KIO { + class Job; +} class CertificateWizardImpl : public CertificateWizard { Q_OBJECT public: CertificateWizardImpl( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); ~CertificateWizardImpl(); - QByteArray keyData() const { return _keyData; } + bool sendToCA() const; + QString caEMailAddress() const; + KURL saveFileUrl() const; -protected slots: + typedef QPair StringLEPair; + typedef QValueVector< StringLEPair > AttrPairList; + +public: + virtual void showPage( QWidget * page ); + virtual void accept(); + +private slots: void slotGenerateCertificate(); - void slotEmailAddressChanged( const QString& text ); + void slotResult( const GpgME::KeyGenerationResult & res, const QByteArray & keyData ); + void slotSetValuesFromWhoAmI(); + void slotEnablePersonalDataPageExit(); + void slotURLSelected( const QString& ); void slotHelpClicked(); + void slotUploadResult( KIO::Job* ); + +private: + void createPersonalDataPage(); + void sendCertificate( const QString& email, const QByteArray& certificateData ); + private: + AttrPairList _attrPairList; QByteArray _keyData; }; #endif // CERTIFICATEWIZARDIMPL_H diff --git a/certmanager.cpp b/certmanager.cpp index 509c45f12..a94b47e12 100644 --- a/certmanager.cpp +++ b/certmanager.cpp @@ -1,1382 +1,1382 @@ /* certmanager.cpp This file is part of Kleopatra, the KDE keymanager Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB Kleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Kleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifdef HAVE_CONFIG_H #include #endif #include "certmanager.h" #include "certlistview.h" #include "certificatewizardimpl.h" #include "certificateinfowidgetimpl.h" #include "crlview.h" #include "customactions.h" #include "hierarchyanalyser.h" #include "storedtransferjob.h" #include "conf/configuredialog.h" // libkleopatra #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // GPGME++ #include #include #include // KDE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Qt #include #include // other #include #include #include namespace { class KDE_EXPORT DisplayStrategy : public Kleo::KeyListView::DisplayStrategy{ public: ~DisplayStrategy() {} virtual QFont keyFont( const GpgME::Key& key, const QFont& font ) const { const Kleo::KeyFilter* filter = Kleo::KeyFilterManager::instance()->filterMatching( key ); return filter ? filter->font( font ) : font; } virtual QColor keyForeground( const GpgME::Key& key, const QColor& c ) const { const Kleo::KeyFilter* filter = Kleo::KeyFilterManager::instance()->filterMatching( key ); if ( filter && filter->fgColor().isValid() ) return filter->fgColor(); return c; } virtual QColor keyBackground( const GpgME::Key& key, const QColor& c ) const { const Kleo::KeyFilter* filter = Kleo::KeyFilterManager::instance()->filterMatching( key ); if ( filter && filter->bgColor().isValid() ) return filter->bgColor(); return c; } }; class KDE_EXPORT ColumnStrategy : public Kleo::KeyListView::ColumnStrategy { public: ~ColumnStrategy() {} QString title( int col ) const; QString text( const GpgME::Key & key, int col ) const; int width( int col, const QFontMetrics & fm ) const; }; QString ColumnStrategy::title( int col ) const { switch ( col ) { case 0: return i18n("Subject"); case 1: return i18n("Issuer"); case 2: return i18n("Serial"); default: return QString::null; } } QString ColumnStrategy::text( const GpgME::Key & key, int col ) const { switch ( col ) { case 0: return Kleo::DN( key.userID(0).id() ).prettyDN(); case 1: return Kleo::DN( key.issuerName() ).prettyDN(); case 2: return key.issuerSerial() ? QString::fromUtf8( key.issuerSerial() ) : QString::null ; default: return QString::null; } } int ColumnStrategy::width( int col, const QFontMetrics & fm ) const { int factor = -1; switch ( col ) { case 0: factor = 6; break; case 1: factor = 4; break; default: return -1; } return fm.width( title( col ) ) * factor; } } // anon namespace CertManager::CertManager( bool remote, const QString& query, const QString & import, QWidget* parent, const char* name, WFlags f ) : KMainWindow( parent, name, f|WDestructiveClose ), mCrlView( 0 ), mDirmngrProc( 0 ), mHierarchyAnalyser( 0 ), mLineEditAction( 0 ), mComboAction( 0 ), mFindAction( 0 ), mImportCertFromFileAction( 0 ), mImportCRLFromFileAction( 0 ), mNextFindRemote( false ), mRemote( remote ), mDirMngrFound( false ) { createStatusBar(); createActions(); createGUI(); setAutoSaveSettings(); // Main Window -------------------------------------------------- mKeyListView = new CertKeyListView( new ColumnStrategy(), new DisplayStrategy(), this, "mKeyListView" ); mKeyListView->setSelectionMode( QListView::Extended ); setCentralWidget( mKeyListView ); connect( mKeyListView, SIGNAL(doubleClicked(Kleo::KeyListViewItem*,const QPoint&,int)), SLOT(slotViewDetails(Kleo::KeyListViewItem*)) ); connect( mKeyListView, SIGNAL(returnPressed(Kleo::KeyListViewItem*)), SLOT(slotViewDetails(Kleo::KeyListViewItem*)) ); connect( mKeyListView, SIGNAL(selectionChanged()), SLOT(slotSelectionChanged()) ); connect( mKeyListView, SIGNAL(contextMenu(Kleo::KeyListViewItem*, const QPoint&)), SLOT(slotContextMenu(Kleo::KeyListViewItem*, const QPoint&)) ); connect( mKeyListView, SIGNAL(dropped(const KURL::List&) ), SLOT( slotDropped(const KURL::List&) ) ); mLineEditAction->setText(query); if ( !mRemote || !query.isEmpty() ) slotSearch(); if ( !import.isEmpty() ) slotImportCertFromFile( KURL( import ) ); readConfig(); updateStatusBarLabels(); slotSelectionChanged(); // initial state for selection-dependent actions } CertManager::~CertManager() { writeConfig(); delete mDirmngrProc; mDirmngrProc = 0; delete mHierarchyAnalyser; mHierarchyAnalyser = 0; } void CertManager::readConfig() { KConfig config( "kleopatrarc" ); config.setGroup( "Display Options" ); slotToggleHierarchicalView( config.readBoolEntry( "hierarchicalView", false ) ); } void CertManager::writeConfig() { KConfig config( "kleopatrarc" ); config.setGroup( "Display Options" ); config.writeEntry( "hierarchicalView", mKeyListView->hierarchical() ); } void CertManager::createStatusBar() { KStatusBar * bar = statusBar(); mProgressBar = new Kleo::ProgressBar( bar, "mProgressBar" ); mProgressBar->reset(); mProgressBar->setFixedSize( QSize( 100, mProgressBar->height() * 3 / 5 ) ); bar->addWidget( mProgressBar, 0, true ); mStatusLabel = new QLabel( bar, "mStatusLabel" ); bar->addWidget( mStatusLabel, 1, false ); } static inline void connectEnableOperationSignal( QObject * s, QObject * d ) { QObject::connect( s, SIGNAL(enableOperations(bool)), d, SLOT(setEnabled(bool)) ); } void CertManager::createActions() { KAction * action = 0; (void)KStdAction::quit( this, SLOT(close()), actionCollection() ); action = KStdAction::redisplay( this, SLOT(slotRedisplay()), actionCollection() ); // work around the fact that the stdaction has no shortcut KShortcut reloadShortcut = KStdAccel::shortcut(KStdAccel::Reload); reloadShortcut.append(KKey(CTRL + Key_R)); action->setShortcut( reloadShortcut ); connectEnableOperationSignal( this, action ); action = new KAction( i18n("Stop Operation"), "stop", Key_Escape, this, SIGNAL(stopOperations()), actionCollection(), "view_stop_operations" ); action->setEnabled( false ); (void) new KAction( i18n("New Key Pair..."), "filenew", 0, this, SLOT(newCertificate()), actionCollection(), "file_new_certificate" ); connect( new KToggleAction( i18n("Hierarchical Key List"), 0, actionCollection(), "view_hierarchical" ), SIGNAL(toggled(bool)), SLOT(slotToggleHierarchicalView(bool)) ); action = new KAction( i18n("Expand All"), 0, CTRL+Key_Period, this, SLOT(slotExpandAll()), actionCollection(), "view_expandall" ); action = new KAction( i18n("Collapse All"), 0, CTRL+Key_Comma, this, SLOT(slotCollapseAll()), actionCollection(), "view_collapseall" ); (void) new KAction( i18n("Refresh CRLs"), 0, 0, this, SLOT(slotRefreshKeys()), actionCollection(), "certificates_refresh_clr" ); #ifdef NOT_IMPLEMENTED_ANYWAY mRevokeCertificateAction = new KAction( i18n("Revoke"), 0, this, SLOT(revokeCertificate()), actionCollection(), "edit_revoke_certificate" ); connectEnableOperationSignal( this, mRevokeCertificateAction ); mExtendCertificateAction = new KAction( i18n("Extend"), 0, this, SLOT(extendCertificate()), actionCollection(), "edit_extend_certificate" ); connectEnableOperationSignal( this, mExtendCertificateAction ); #endif mDeleteCertificateAction = new KAction( i18n("Delete"), "editdelete", Key_Delete, this, SLOT(slotDeleteCertificate()), actionCollection(), "edit_delete_certificate" ); connectEnableOperationSignal( this, mDeleteCertificateAction ); mValidateCertificateAction = new KAction( i18n("Validate"), "reload", SHIFT + Key_F5, this, SLOT(slotValidate()), actionCollection(), "certificates_validate" ); connectEnableOperationSignal( this, mValidateCertificateAction ); mImportCertFromFileAction = new KAction( i18n("Import Certificates..."), 0, this, SLOT(slotImportCertFromFile()), actionCollection(), "file_import_certificates" ); connectEnableOperationSignal( this, mImportCertFromFileAction ); mImportCRLFromFileAction = new KAction( i18n("Import CRLs..."), 0, this, SLOT(importCRLFromFile()), actionCollection(), "file_import_crls" ); connectEnableOperationSignal( this, mImportCRLFromFileAction ); mExportCertificateAction = new KAction( i18n("Export Certificates..."), "export", 0, this, SLOT(slotExportCertificate()), actionCollection(), "file_export_certificate" ); mExportSecretKeyAction = new KAction( i18n("Export Secret Key..."), "export", 0, this, SLOT(slotExportSecretKey()), actionCollection(), "file_export_secret_keys" ); connectEnableOperationSignal( this, mExportSecretKeyAction ); mViewCertDetailsAction = new KAction( i18n("Certificate Details..."), 0, 0, this, SLOT(slotViewDetails()), actionCollection(), "view_certificate_details" ); mDownloadCertificateAction = new KAction( i18n( "Download"), 0, 0, this, SLOT(slotDownloadCertificate()), actionCollection(), "download_certificate" ); const QString dirmngr = KStandardDirs::findExe( "gpgsm" ); mDirMngrFound = !dirmngr.isEmpty(); action = new KAction( i18n("Dump CRL Cache..."), 0, this, SLOT(slotViewCRLs()), actionCollection(), "crl_dump_crl_cache" ); action->setEnabled( mDirMngrFound ); // we also need dirmngr for this action = new KAction( i18n("Clear CRL Cache..."), 0, this, SLOT(slotClearCRLs()), actionCollection(), "crl_clear_crl_cache" ); action->setEnabled( mDirMngrFound ); // we also need dirmngr for this action = new KAction( i18n("GnuPG Log Viewer..."), "pgp-keys", 0, this, SLOT(slotStartWatchGnuPG()), actionCollection(), "tools_start_kwatchgnupg"); // disable action if no kwatchgnupg binary is around if (KStandardDirs::findExe("kwatchgnupg").isEmpty()) action->setEnabled(false); (void)new LabelAction( i18n("Search:"), actionCollection(), "label_action" ); mLineEditAction = new LineEditAction( QString::null, actionCollection(), this, SLOT(slotSearch()), "query_lineedit_action"); QStringList lst; lst << i18n("In Local Certificates") << i18n("In External Certificates"); mComboAction = new ComboAction( lst, actionCollection(), this, SLOT( slotToggleRemote(int) ), "location_combo_action"); mFindAction = new KAction( i18n("Find"), "find", 0, this, SLOT(slotSearch()), actionCollection(), "find" ); KStdAction::keyBindings( this, SLOT(slotEditKeybindings()), actionCollection() ); KStdAction::preferences( this, SLOT(slotShowConfigurationDialog()), actionCollection() ); new KAction( i18n( "Configure &GpgME Backend" ), 0, 0, this, SLOT(slotConfigureGpgME()), actionCollection(), "configure_gpgme" ); createStandardStatusBarAction(); updateImportActions( true ); } void CertManager::updateImportActions( bool enable ) { mImportCRLFromFileAction->setEnabled( mDirMngrFound && enable ); mImportCertFromFileAction->setEnabled( enable ); } void CertManager::slotEditKeybindings() { KKeyDialog::configure( actionCollection(), true ); } void CertManager::slotShowConfigurationDialog() { ConfigureDialog dlg( this ); connect( &dlg, SIGNAL( configCommitted() ), SLOT( slotRepaint() ) ); dlg.exec(); } void CertManager::slotConfigureGpgME() { Kleo::CryptoConfig* config = Kleo::CryptoBackendFactory::instance()->config(); if ( config ) { Kleo::CryptoConfigDialog dlg( config ); int result = dlg.exec(); // Forget all data parsed from gpgconf, so that we show updated information // when reopening the configuration dialog. config->clear(); if ( result == QDialog::Accepted ) { // Tell other apps (e.g. kmail) that the gpgconf data might have changed kapp->dcopClient()->emitDCOPSignal( "KPIM::CryptoConfig", "changed()", QByteArray() ); } } } void CertManager::slotRepaint() { mKeyListView->repaintContents(); } void CertManager::slotToggleRemote( int idx ) { mNextFindRemote = idx != 0; } void CertManager::slotToggleHierarchicalView( bool hier ) { mKeyListView->setHierarchical( hier ); mKeyListView->setRootIsDecorated( hier ); if ( KAction * act = action("view_expandall") ) act->setEnabled( hier ); if ( KAction * act = action("view_collapseall" ) ) act->setEnabled( hier ); if ( KToggleAction * act = static_cast( action("view_hierarchical") ) ) act->setChecked( hier ); if ( hier && !mCurrentQuery.isEmpty() ) startRedisplay( false ); } void CertManager::slotExpandAll() { for ( QListViewItemIterator it( mKeyListView ) ; it.current() ; ++it ) it.current()->setOpen( true ); } void CertManager::slotCollapseAll() { for ( QListViewItemIterator it( mKeyListView ) ; it.current() ; ++it ) it.current()->setOpen( false ); } void CertManager::connectJobToStatusBarProgress( Kleo::Job * job, const QString & initialText ) { assert( mProgressBar ); if ( !job ) return; if ( !initialText.isEmpty() ) statusBar()->message( initialText ); connect( job, SIGNAL(progress(const QString&,int,int)), mProgressBar, SLOT(slotProgress(const QString&,int,int)) ); connect( job, SIGNAL(done()), mProgressBar, SLOT(reset()) ); connect( this, SIGNAL(stopOperations()), job, SLOT(slotCancel()) ); action("view_stop_operations")->setEnabled( true ); emit enableOperations( false ); } void CertManager::disconnectJobFromStatusBarProgress( const GpgME::Error & err ) { updateStatusBarLabels(); const QString msg = err.isCanceled() ? i18n("Canceled.") : err ? i18n("Failed.") : i18n("Done.") ; statusBar()->message( msg, 4000 ); action("view_stop_operations")->setEnabled( false ); emit enableOperations( true ); slotSelectionChanged(); } void CertManager::updateStatusBarLabels() { mKeyListView->flushKeys(); int total = 0; for ( QListViewItemIterator it( mKeyListView ) ; it.current() ; ++it ) ++total; mStatusLabel->setText( i18n( "%n Key.","%n Keys.", total ) ); } // // // Key Listing: // // static std::set extractKeyFingerprints( const QPtrList & items ) { std::set result; for ( QPtrListIterator it( items ) ; it.current() ; ++it ) if ( const char * fpr = it.current()->key().primaryFingerprint() ) result.insert( fpr ); return result; } static QStringList stringlistFromSet( const std::set & set ) { // ARGH. This is madness. Shitty Qt containers don't support QStringList( patterns.begin(), patterns.end() ) :/ QStringList sl; for ( std::set::const_iterator it = set.begin() ; it != set.end() ; ++it ) // let's make extra sure, maybe someone tries to make Qt not support std::string->QString conversion sl.push_back( QString::fromLatin1( it->c_str() ) ); return sl; } void CertManager::slotRefreshKeys() { const QStringList keys = stringlistFromSet( extractKeyFingerprints( mKeyListView->selectedItems() ) ); Kleo::RefreshKeysJob * job = Kleo::CryptoBackendFactory::instance()->smime()->refreshKeysJob(); assert( job ); connect( job, SIGNAL(result(const GpgME::Error&)), this, SLOT(slotRefreshKeysResult(const GpgME::Error&)) ); connectJobToStatusBarProgress( job, i18n("Refreshing keys...") ); if ( const GpgME::Error err = job->start( keys ) ) slotRefreshKeysResult( err ); } void CertManager::slotRefreshKeysResult( const GpgME::Error & err ) { disconnectJobFromStatusBarProgress( err ); if ( err.isCanceled() ) return; if ( err ) KMessageBox::error( this, i18n("An error occurred while trying to refresh " "keys:\n%1").arg( QString::fromLocal8Bit( err.asString() ) ), i18n("Refreshing Keys Failed") ); } static void showKeyListError( QWidget * parent, const GpgME::Error & err ) { assert( err ); const QString msg = i18n( "

An error occurred while fetching " "the certificates from the backend:

" "

%1

" ) .arg( QString::fromLocal8Bit( err.asString() ) ); KMessageBox::error( parent, msg, i18n( "Certificate Listing Failed" ) ); } void CertManager::slotSearch() { mPreviouslySelectedFingerprints.clear(); // Clear display mKeyListView->clear(); mCurrentQuery = mLineEditAction->text(); startKeyListing( false, false, mCurrentQuery ); } void CertManager::startRedisplay( bool validate ) { mPreviouslySelectedFingerprints = extractKeyFingerprints( mKeyListView->selectedItems() ); if ( mPreviouslySelectedFingerprints.empty() ) startKeyListing( validate, true, mCurrentQuery ); else startKeyListing( validate, true, mPreviouslySelectedFingerprints ); } void CertManager::startKeyListing( bool validating, bool refresh, const std::set & patterns ) { startKeyListing( validating, refresh, stringlistFromSet( patterns ) ); } void CertManager::startKeyListing( bool validating, bool refresh, const QStringList & patterns ) { mRemote = mNextFindRemote; mLineEditAction->setEnabled( false ); mComboAction->setEnabled( false ); mFindAction->setEnabled( false ); Kleo::KeyListJob * job = 0; if ( !validating && !refresh && mKeyListView->hierarchical() && !patterns.empty() ) job = new Kleo::HierarchicalKeyListJob( Kleo::CryptoBackendFactory::instance()->smime(), mRemote, false, validating ); else job = Kleo::CryptoBackendFactory::instance()->smime()->keyListJob( mRemote, false, validating ); assert( job ); connect( job, SIGNAL(nextKey(const GpgME::Key&)), mKeyListView, refresh ? SLOT(slotRefreshKey(const GpgME::Key&)) : SLOT(slotAddKey(const GpgME::Key&)) ); connect( job, SIGNAL(result(const GpgME::KeyListResult&)), this, SLOT(slotKeyListResult(const GpgME::KeyListResult&)) ); connectJobToStatusBarProgress( job, i18n("Fetching keys...") ); const GpgME::Error err = job->start( patterns ) ; if ( err ) { showKeyListError( this, err ); return; } mProgressBar->setProgress( 0, 0 ); // enable busy indicator } static void selectKeys( Kleo::KeyListView * lv, const std::set & fprs ) { if ( !lv || fprs.empty() ) return; for ( QListViewItemIterator it( lv ) ; it.current() ; ++it ) if ( Kleo::KeyListViewItem * item = Kleo::lvi_cast( it.current() ) ) { const char * fpr = item->key().primaryFingerprint(); item->setSelected( fpr && fprs.find( fpr ) != fprs.end() ); } } void CertManager::slotKeyListResult( const GpgME::KeyListResult & res ) { if ( res.error() ) showKeyListError( this, res.error() ); else if ( res.isTruncated() ) KMessageBox::information( this, i18n("The query result has been truncated.\n" "Either the local or a remote limit on " "the maximum number of returned hits has " "been exceeded.\n" "You can try to increase the local limit " "in the configuration dialog, but if one " "of the configured servers is the limiting " "factor, you have to refine your search.") ); mLineEditAction->setEnabled( true ); mComboAction->setEnabled( true ); mFindAction->setEnabled( true ); mLineEditAction->focusAll(); disconnectJobFromStatusBarProgress( res.error() ); selectKeys( mKeyListView, mPreviouslySelectedFingerprints ); } void CertManager::slotContextMenu(Kleo::KeyListViewItem* item, const QPoint& point) { if ( !item ) return; if ( QPopupMenu * popup = static_cast(factory()->container("listview_popup",this)) ) popup->exec( point ); } /** This slot is invoked when the user selects "New certificate" */ void CertManager::newCertificate() { CertificateWizardImpl wizard( this ); wizard.exec(); } /** This slot is invoked when the user selects revoke certificate. The slot will revoke the selected certificates */ void CertManager::revokeCertificate() { qDebug("Not Yet Implemented"); } /** This slot is invoked when the user selects extend certificate. It will send an extension request for the selected certificates */ void CertManager::extendCertificate() { qDebug("Not Yet Implemented"); } // // // Downloading / Importing Certificates // // /** This slot is invoked when the user selects Certificates/Import/From File. */ void CertManager::slotImportCertFromFile() { const QString filter = "application/x-x509-ca-cert application/x-pkcs12 application/pkcs7-mime"; //const QString filter = QString("*.pem *.der *.p7c *.p12|") + i18n("Certificates (*.pem *.der *.p7c *.p12)"); slotImportCertFromFile( KFileDialog::getOpenURL( QString::null, filter, this, i18n( "Select Certificate File" ) ) ); } void CertManager::slotImportCertFromFile( const KURL & certURL ) { if ( !certURL.isValid() ) // empty or malformed return; mPreviouslySelectedFingerprints.clear(); // Prevent two simultaneous imports updateImportActions( false ); // Download the cert KIOext::StoredTransferJob* importJob = KIOext::storedGet( certURL ); importJob->setWindow( this ); connect( importJob, SIGNAL(result(KIO::Job*)), SLOT(slotImportResult(KIO::Job*)) ); } void CertManager::slotImportResult( KIO::Job* job ) { if ( job->error() ) { job->showErrorDialog(); } else { KIOext::StoredTransferJob* trJob = static_cast( job ); startCertificateImport( trJob->data(), trJob->url().fileName() ); } updateImportActions( true ); } static void showCertificateDownloadError( QWidget * parent, const GpgME::Error & err, const QString& certDisplayName ) { assert( err ); const QString msg = i18n( "

An error occurred while trying " "to download the certificate %1:

" "

%2

" ) .arg( certDisplayName ) .arg( QString::fromLocal8Bit( err.asString() ) ); KMessageBox::error( parent, msg, i18n( "Certificate Download Failed" ) ); } void CertManager::slotDownloadCertificate() { mPreviouslySelectedFingerprints.clear(); QPtrList items = mKeyListView->selectedItems(); for ( QPtrListIterator it( items ) ; it.current() ; ++it ) if ( !it.current()->key().isNull() ) if ( const char * fpr = it.current()->key().primaryFingerprint() ) slotStartCertificateDownload( fpr, it.current()->text(0) ); } // Called from slotDownloadCertificate and from the certificate-details widget void CertManager::slotStartCertificateDownload( const QString& fingerprint, const QString& displayName ) { if ( fingerprint.isEmpty() ) return; Kleo::DownloadJob * job = Kleo::CryptoBackendFactory::instance()->smime()->downloadJob( false /* no armor */ ); assert( job ); connect( job, SIGNAL(result(const GpgME::Error&,const QByteArray&)), SLOT(slotCertificateDownloadResult(const GpgME::Error&,const QByteArray&)) ); connectJobToStatusBarProgress( job, i18n("Fetching certificate from server...") ); const GpgME::Error err = job->start( fingerprint ); if ( err ) showCertificateDownloadError( this, err, displayName ); else { mProgressBar->setProgress( 0, 0 ); mJobsDisplayNameMap.insert( job, displayName ); } } QString CertManager::displayNameForJob( const Kleo::Job *job ) { JobsDisplayNameMap::iterator it = mJobsDisplayNameMap.find( job ); QString displayName; if ( it != mJobsDisplayNameMap.end() ) { displayName = *it; mJobsDisplayNameMap.remove( it ); } else { kdWarning() << "Job not found in map: " << job << endl; } return displayName; } // Don't call directly! void CertManager::slotCertificateDownloadResult( const GpgME::Error & err, const QByteArray & keyData ) { QString displayName = displayNameForJob( static_cast( sender() ) ); if ( err ) showCertificateDownloadError( this, err, displayName ); else startCertificateImport( keyData, displayName ); disconnectJobFromStatusBarProgress( err ); } static void showCertificateImportError( QWidget * parent, const GpgME::Error & err, const QString& certDisplayName ) { assert( err ); const QString msg = i18n( "

An error occurred while trying " "to import the certificate %1:

" "

%2

" ) .arg( certDisplayName ) .arg( QString::fromLocal8Bit( err.asString() ) ); KMessageBox::error( parent, msg, i18n( "Certificate Import Failed" ) ); } void CertManager::startCertificateImport( const QByteArray & keyData, const QString& certDisplayName ) { Kleo::ImportJob * job = Kleo::CryptoBackendFactory::instance()->smime()->importJob(); assert( job ); connect( job, SIGNAL(result(const GpgME::ImportResult&)), SLOT(slotCertificateImportResult(const GpgME::ImportResult&)) ); connectJobToStatusBarProgress( job, i18n("Importing certificates...") ); kdDebug() << "Importing certificate. keyData size:" << keyData.size() << endl; const GpgME::Error err = job->start( keyData ); if ( err ) showCertificateImportError( this, err, certDisplayName ); else { mProgressBar->setProgress( 0, 0 ); mJobsDisplayNameMap.insert( job, certDisplayName ); } } void CertManager::slotCertificateImportResult( const GpgME::ImportResult & res ) { QString displayName = displayNameForJob( static_cast( sender() ) ); if ( res.error().isCanceled() ) { // do nothing } else if ( res.error() ) { showCertificateImportError( this, res.error(), displayName ); } else { const QString normalLine = i18n("%1%2"); const QString boldLine = i18n("%1%2"); QStringList lines; lines.push_back( normalLine.arg( i18n("Total number processed:"), QString::number( res.numConsidered() ) ) ); lines.push_back( normalLine.arg( i18n("Imported:"), QString::number( res.numImported() ) ) ); if ( res.newSignatures() ) lines.push_back( normalLine.arg( i18n("New signatures:"), QString::number( res.newSignatures() ) ) ); if ( res.newUserIDs() ) lines.push_back( normalLine.arg( i18n("New user IDs:"), QString::number( res.newUserIDs() ) ) ); if ( res.numKeysWithoutUserID() ) lines.push_back( normalLine.arg( i18n("Keys without user IDs:"), QString::number( res.numKeysWithoutUserID() ) ) ); if ( res.newSubkeys() ) lines.push_back( normalLine.arg( i18n("New subkeys:"), QString::number( res.newSubkeys() ) ) ); if ( res.newRevocations() ) lines.push_back( boldLine.arg( i18n("Newly revoked:"), QString::number( res.newRevocations() ) ) ); if ( res.notImported() ) lines.push_back( boldLine.arg( i18n("Not imported:"), QString::number( res.notImported() ) ) ); if ( res.numUnchanged() ) lines.push_back( normalLine.arg( i18n("Unchanged:"), QString::number( res.numUnchanged() ) ) ); if ( res.numSecretKeysConsidered() ) lines.push_back( normalLine.arg( i18n("Secret keys processed:"), QString::number( res.numSecretKeysConsidered() ) ) ); if ( res.numSecretKeysImported() ) lines.push_back( normalLine.arg( i18n("Secret keys imported:"), QString::number( res.numSecretKeysImported() ) ) ); if ( res.numSecretKeysConsidered() - res.numSecretKeysImported() - res.numSecretKeysUnchanged() > 0 ) lines.push_back( boldLine.arg( i18n("Secret keys not imported:"), QString::number( res.numSecretKeysConsidered() - res.numSecretKeysImported() - res.numSecretKeysUnchanged() ) ) ); if ( res.numSecretKeysUnchanged() ) lines.push_back( normalLine.arg( i18n("Secret keys unchanged:"), QString::number( res.numSecretKeysUnchanged() ) ) ); KMessageBox::information( this, i18n( "

Detailed results of importing %1:

" "%2
" ) .arg( displayName ).arg( lines.join( QString::null ) ), i18n( "Certificate Import Result" ) ); disconnectJobFromStatusBarProgress( res.error() ); // save the fingerprints of imported certs for later selection: const std::vector imports = res.imports(); for ( std::vector::const_iterator it = imports.begin() ; it != imports.end() ; ++it ) mPreviouslySelectedFingerprints.insert( it->fingerprint() ); } importNextURLOrRedisplay(); } /** This slot is called when the dirmngr process that imports a certificate file exists. */ void CertManager::slotDirmngrExited() { if ( !mDirmngrProc->normalExit() ) KMessageBox::error( this, i18n( "The GpgSM process that tried to import the CRL file ended prematurely because of an unexpected error." ), i18n( "Certificate Manager Error" ) ); else if ( mDirmngrProc->exitStatus() ) KMessageBox::error( this, i18n( "An error occurred when trying to import the CRL file. The output from GpgSM was:\n%1").arg( mErrorbuffer ), i18n( "Certificate Manager Error" ) ); else KMessageBox::information( this, i18n( "CRL file imported successfully." ), i18n( "Certificate Manager Information" ) ); delete mDirmngrProc; mDirmngrProc = 0; if ( !mImportCRLTempFile.isEmpty() ) QFile::remove( mImportCRLTempFile ); updateImportActions( true ); } /** This slot will import CRLs from a file. */ void CertManager::importCRLFromFile() { QString filter = QString("*.crl *.arl *-crl.der *-arl.der|") + i18n("Certificate Revocation List (*.crl *.arl *-crl.der *-arl.der)"); KURL url = KFileDialog::getOpenURL( QString::null, filter, this, i18n( "Select CRL File" ) ); if ( url.isValid() ) { updateImportActions( false ); if ( url.isLocalFile() ) { startImportCRL( url.path(), false ); updateImportActions( true ); } else { KTempFile tempFile; KURL destURL; destURL.setPath( tempFile.name() ); KIO::Job* copyJob = KIO::file_copy( url, destURL, 0600, true, false ); copyJob->setWindow( this ); connect( copyJob, SIGNAL( result( KIO::Job * ) ), SLOT( slotImportCRLJobFinished( KIO::Job * ) ) ); } } } void CertManager::slotImportCRLJobFinished( KIO::Job *job ) { KIO::FileCopyJob* fcjob = static_cast( job ); QString tempFilePath = fcjob->destURL().path(); if ( job->error() ) { job->showErrorDialog(); QFile::remove( tempFilePath ); // unlink tempfile updateImportActions( true ); return; } startImportCRL( tempFilePath, true ); } bool CertManager::connectAndStartDirmngr( const char * slot, const char * processname ) { assert( slot ); assert( processname ); assert( mDirmngrProc ); mErrorbuffer = QString::null; connect( mDirmngrProc, SIGNAL(processExited(KProcess*)), slot ); connect( mDirmngrProc, SIGNAL(receivedStderr(KProcess*,char*,int) ), this, SLOT(slotStderr(KProcess*,char*,int)) ); if( !mDirmngrProc->start( KProcess::NotifyOnExit, KProcess::Stderr ) ) { delete mDirmngrProc; mDirmngrProc = 0; KMessageBox::error( this, i18n( "Unable to start %1 process. Please check your installation." ).arg( processname ), i18n( "Certificate Manager Error" ) ); return false; } return true; } void CertManager::startImportCRL( const QString& filename, bool isTempFile ) { assert( !mDirmngrProc ); mImportCRLTempFile = isTempFile ? filename : QString::null; mDirmngrProc = new KProcess(); *mDirmngrProc << "gpgsm" << "--call-dirmngr" << "loadcrl" << filename; if ( !connectAndStartDirmngr( SLOT(slotDirmngrExited()), "gpgsm" ) ) { updateImportActions( true ); if ( isTempFile ) QFile::remove( mImportCRLTempFile ); // unlink tempfile } } void CertManager::startClearCRLs() { assert( !mDirmngrProc ); mDirmngrProc = new KProcess(); *mDirmngrProc << "dirmngr" << "--flush"; //*mDirmngrProc << "gpgsm" << "--call-dimngr" << "flush"; // use this once it's implemented! connectAndStartDirmngr( SLOT(slotClearCRLsResult()), "dirmngr" ); } void CertManager::slotStderr( KProcess*, char* buf, int len ) { mErrorbuffer += QString::fromLocal8Bit( buf, len ); } /** This slot will import CRLs from an LDAP server. */ void CertManager::importCRLFromLDAP() { qDebug("Not Yet Implemented"); } void CertManager::slotViewCRLs() { if ( !mCrlView ) mCrlView = new CRLView( this ); mCrlView->show(); mCrlView->slotUpdateView(); } void CertManager::slotClearCRLs() { startClearCRLs(); } void CertManager::slotClearCRLsResult() { assert( mDirmngrProc ); if ( !mDirmngrProc->normalExit() ) KMessageBox::error( this, i18n( "The DirMngr process that tried to clear the CRL cache ended prematurely because of an unexpected error." ), i18n( "Certificate Manager Error" ) ); else if ( mDirmngrProc->exitStatus() ) KMessageBox::error( this, i18n( "An error occurred when trying to clear the CRL cache. The output from DirMngr was:\n%1").arg( mErrorbuffer ), i18n( "Certificate Manager Error" ) ); else KMessageBox::information( this, i18n( "CRL cache cleared successfully." ), i18n( "Certificate Manager Information" ) ); delete mDirmngrProc; mDirmngrProc = 0; } static void showDeleteError( QWidget * parent, const GpgME::Error & err ) { assert( err ); const QString msg = i18n("

An error occurred while trying to delete " "the certificates:

" "

%1

") .arg( QString::fromLocal8Bit( err.asString() ) ); KMessageBox::error( parent, msg, i18n("Certificate Deletion Failed") ); } static bool ByFingerprint( const GpgME::Key & left, const GpgME::Key & right ) { return qstricmp( left.primaryFingerprint(), right.primaryFingerprint() ) < 0 ; } static bool WithRespectToFingerprints( const GpgME::Key & left, const GpgME::Key & right ) { return qstricmp( left.primaryFingerprint(), right.primaryFingerprint() ) == 0; } void CertManager::slotDeleteCertificate() { mItemsToDelete = mKeyListView->selectedItems(); if ( mItemsToDelete.isEmpty() ) return; std::vector keys; keys.reserve( mItemsToDelete.count() ); QStringList keyDisplayNames; for ( QPtrListIterator it( mItemsToDelete ) ; it.current() ; ++it ) if ( !it.current()->key().isNull() ) { keys.push_back( it.current()->key() ); keyDisplayNames.push_back( it.current()->text( 0 ) ); } if ( keys.empty() ) return; if ( !mHierarchyAnalyser ) { mHierarchyAnalyser = new HierarchyAnalyser( this, "mHierarchyAnalyser" ); Kleo::KeyListJob * job = Kleo::CryptoBackendFactory::instance()->smime()->keyListJob(); assert( job ); connect( job, SIGNAL(nextKey(const GpgME::Key&)), mHierarchyAnalyser, SLOT(slotNextKey(const GpgME::Key&)) ); connect( job, SIGNAL(result(const GpgME::KeyListResult&)), this, SLOT(slotDeleteCertificate()) ); connectJobToStatusBarProgress( job, i18n("Checking key dependencies...") ); if ( const GpgME::Error error = job->start( QStringList() ) ) { showKeyListError( this, error ); delete mHierarchyAnalyser; mHierarchyAnalyser = 0; } return; } else disconnectJobFromStatusBarProgress( 0 ); std::vector keysToDelete = keys; for ( std::vector::const_iterator it = keys.begin() ; it != keys.end() ; ++it ) if ( !it->isNull() ) { const std::vector subjects = mHierarchyAnalyser->subjectsForIssuerRecursive( it->primaryFingerprint() ); keysToDelete.insert( keysToDelete.end(), subjects.begin(), subjects.end() ); } std::sort( keysToDelete.begin(), keysToDelete.end(), ByFingerprint ); keysToDelete.erase( std::unique( keysToDelete.begin(), keysToDelete.end(), WithRespectToFingerprints ), keysToDelete.end() ); delete mHierarchyAnalyser; mHierarchyAnalyser = 0; if ( keysToDelete.size() > keys.size() ) if ( KMessageBox::warningContinueCancel( this, i18n("Some or all of the selected " "certificates are issuers (CA certificates) " "for other, non-selected certificates.\n" "Deleting a CA certificate will also delete " "all certificates issued by it."), i18n("Deleting CA Certificates") ) != KMessageBox::Continue ) return; const QString msg = keysToDelete.size() > keys.size() ? i18n("Do you really want to delete this certificate and the %1 certificates it certified?", "Do you really want to delete these %n certificates and the %1 certificates they certified?", keys.size() ).arg( keysToDelete.size() - keys.size() ) : i18n("Do you really want to delete this certificate?", "Do you really want to delete these %n certificates?", keys.size() ) ; if ( KMessageBox::warningContinueCancelList( this, msg, keyDisplayNames, i18n( "Delete Certificates" ), KGuiItem( i18n( "Delete" ), "editdelete" ), "ConfirmDeleteCert", KMessageBox::Dangerous ) != KMessageBox::Continue ) return; if ( Kleo::DeleteJob * job = Kleo::CryptoBackendFactory::instance()->smime()->deleteJob() ) job->slotCancel(); else { QString str = keys.size() == 1 ? i18n("

An error occurred while trying to delete " "the certificate:

" "

%1

" ) : i18n( "

An error occurred while trying to delete " "the certificates:

" "

%1

" ); KMessageBox::error( this, str.arg( i18n("Operation not supported by the backend.") ), i18n("Certificate Deletion Failed") ); } mItemsToDelete.clear(); // re-create according to the real selection for ( std::vector::const_iterator it = keysToDelete.begin() ; it != keysToDelete.end() ; ++it ) if ( Kleo::KeyListViewItem * item = mKeyListView->itemByFingerprint( it->primaryFingerprint() ) ) mItemsToDelete.append( item ); Kleo::MultiDeleteJob * job = new Kleo::MultiDeleteJob( Kleo::CryptoBackendFactory::instance()->smime() ); assert( job ); connect( job, SIGNAL(result(const GpgME::Error&,const GpgME::Key&)), SLOT(slotDeleteResult(const GpgME::Error&,const GpgME::Key&)) ); connectJobToStatusBarProgress( job, i18n("Deleting keys...") ); const GpgME::Error err = job->start( keys, true ); if ( err ) showDeleteError( this, err ); else mProgressBar->setProgress( 0, 0 ); } void CertManager::slotDeleteResult( const GpgME::Error & err, const GpgME::Key & ) { if ( err ) showDeleteError( this, err ); else { const int infinity = 100; // infinite loop guard... mItemsToDelete.setAutoDelete( true ); for ( int i = 0 ; i < infinity ; ++i ) { QPtrListIterator it( mItemsToDelete ); while ( Kleo::KeyListViewItem * cur = it.current() ) { ++it; if ( cur->childCount() == 0 ) { mItemsToDelete.remove( cur ); } } if ( mItemsToDelete.isEmpty() ) break; } mItemsToDelete.setAutoDelete( false ); Q_ASSERT( mItemsToDelete.isEmpty() ); mItemsToDelete.clear(); } disconnectJobFromStatusBarProgress( err ); } void CertManager::slotViewDetails( Kleo::KeyListViewItem * item ) { if ( !item || item->key().isNull() ) return; // KDialogBase * dialog = new KDialogBase( this, "dialog", false, i18n("Additional Information for Key"), KDialogBase::Close, KDialogBase::Close ); CertificateInfoWidgetImpl * top = new CertificateInfoWidgetImpl( item->key(), isRemote(), dialog ); dialog->setMainWidget( top ); // connect( top, SIGNAL(requestCertificateDownload(const QString&, const QString&)), SLOT(slotStartCertificateDownload(const QString&, const QString&)) ); dialog->show(); } void CertManager::slotViewDetails() { QPtrList items = mKeyListView->selectedItems(); if ( items.isEmpty() ) return; // selectedItem() doesn't work in Extended mode. // But we only want to show the details of one item... slotViewDetails( items.first() ); } void CertManager::slotSelectionChanged() { mKeyListView->flushKeys(); bool b = mKeyListView->hasSelection(); mExportCertificateAction->setEnabled( b ); mViewCertDetailsAction->setEnabled( b ); mDeleteCertificateAction->setEnabled( b ); #ifdef NOT_IMPLEMENTED_ANYWAY mRevokeCertificateAction->setEnabled( b ); mExtendCertificateAction->setEnabled( b ); #endif mDownloadCertificateAction->setEnabled( b && mRemote ); mValidateCertificateAction->setEnabled( !mRemote ); } void CertManager::slotExportCertificate() { QPtrList items = mKeyListView->selectedItems(); if ( items.isEmpty() ) return; QStringList fingerprints; for ( QPtrListIterator it( items ) ; it.current() ; ++it ) if ( !it.current()->key().isNull() ) if ( const char * fpr = it.current()->key().primaryFingerprint() ) fingerprints.push_back( fpr ); startCertificateExport( fingerprints ); } static void showCertificateExportError( QWidget * parent, const GpgME::Error & err ) { assert( err ); const QString msg = i18n("

An error occurred while trying to export " "the certificate:

" "

%1

") .arg( QString::fromLocal8Bit( err.asString() ) ); KMessageBox::error( parent, msg, i18n("Certificate Export Failed") ); } void CertManager::startCertificateExport( const QStringList & fingerprints ) { if ( fingerprints.empty() ) return; // we need to use PEM (ascii armoured) format, since DER (binary) // can't transport more than one certificate *sigh* this is madness :/ Kleo::ExportJob * job = Kleo::CryptoBackendFactory::instance()->smime()->publicKeyExportJob( true ); assert( job ); connect( job, SIGNAL(result(const GpgME::Error&,const QByteArray&)), SLOT(slotCertificateExportResult(const GpgME::Error&,const QByteArray&)) ); connectJobToStatusBarProgress( job, i18n("Exporting certificate...") ); const GpgME::Error err = job->start( fingerprints ); if ( err ) showCertificateExportError( this, err ); else mProgressBar->setProgress( 0, 0 ); } // return true if we should proceed, false if we should abort static bool checkOverwrite( const KURL& url, bool& overwrite, QWidget* w ) { if ( KIO::NetAccess::exists( url, false /*dest*/, w ) ) { if ( KMessageBox::Cancel == KMessageBox::warningContinueCancel( w, i18n( "A file named \"%1\" already exists. " "Are you sure you want to overwrite it?" ).arg( url.prettyURL() ), i18n( "Overwrite File?" ), i18n( "&Overwrite" ) ) ) return false; overwrite = true; } return true; } void CertManager::slotCertificateExportResult( const GpgME::Error & err, const QByteArray & data ) { disconnectJobFromStatusBarProgress( err ); if ( err ) { showCertificateExportError( this, err ); return; } kdDebug() << "CertManager::slotCertificateExportResult(): got " << data.size() << " bytes" << endl; const QString filter = QString("*.pem|") + i18n("ASCII Armored Certificate Bundles (*.pem)"); const KURL url = KFileDialog::getOpenURL( QString::null, filter, this, i18n( "Save Certificate" ) ); if ( !url.isValid() ) return; bool overwrite = false; if ( !checkOverwrite( url, overwrite, this ) ) return; KIO::Job* uploadJob = KIOext::put( data, url, -1, overwrite, false /*resume*/ ); uploadJob->setWindow( this ); connect( uploadJob, SIGNAL( result( KIO::Job* ) ), this, SLOT( slotUploadResult( KIO::Job* ) ) ); } void CertManager::slotExportSecretKey() { Kleo::KeySelectionDialog dlg( i18n("Secret Key Export"), i18n("Select the secret key to export " "(Warning: The PKCS#12 format is insecure; " "exporting secret keys is discouraged):"), std::vector(), Kleo::KeySelectionDialog::SecretKeys|Kleo::KeySelectionDialog::SMIMEKeys, false /* no multiple selection */, false /* no remember choice box */, this, "secret key export key selection dialog" ); //dlg.setHideInvalidKeys( false ); if ( dlg.exec() != QDialog::Accepted ) return; startSecretKeyExport( dlg.fingerprint() ); } static void showSecretKeyExportError( QWidget * parent, const GpgME::Error & err ) { assert( err ); const QString msg = i18n("

An error occurred while trying to export " "the secret key:

" "

%1

") .arg( QString::fromLocal8Bit( err.asString() ) ); KMessageBox::error( parent, msg, i18n("Secret-Key Export Failed") ); } void CertManager::startSecretKeyExport( const QString & fingerprint ) { if ( fingerprint.isEmpty() ) return; // PENDING(marc): let user choose between binary and PEM format? Kleo::ExportJob * job = Kleo::CryptoBackendFactory::instance()->smime()->secretKeyExportJob( false ); assert( job ); connect( job, SIGNAL(result(const GpgME::Error&,const QByteArray&)), SLOT(slotSecretKeyExportResult(const GpgME::Error&,const QByteArray&)) ); connectJobToStatusBarProgress( job, i18n("Exporting secret key...") ); const GpgME::Error err = job->start( fingerprint ); if ( err ) showSecretKeyExportError( this, err ); else mProgressBar->setProgress( 0, 0 ); } void CertManager::slotSecretKeyExportResult( const GpgME::Error & err, const QByteArray & data ) { disconnectJobFromStatusBarProgress( err ); if ( err ) { showSecretKeyExportError( this, err ); return; } kdDebug() << "CertManager::slotSecretKeyExportResult(): got " << data.size() << " bytes" << endl; QString filter = QString("*.p12|") + i18n("PKCS#12 Key Bundle (*.p12)"); KURL url = KFileDialog::getOpenURL( QString::null, filter, this, i18n( "Save Certificate" ) ); if ( !url.isValid() ) return; bool overwrite = false; if ( !checkOverwrite( url, overwrite, this ) ) return; KIO::Job* uploadJob = KIOext::put( data, url, -1, overwrite, false /*resume*/ ); uploadJob->setWindow( this ); connect( uploadJob, SIGNAL( result( KIO::Job* ) ), this, SLOT( slotUploadResult( KIO::Job* ) ) ); } void CertManager::slotUploadResult( KIO::Job* job ) { if ( job->error() ) job->showErrorDialog(); } void CertManager::slotDropped(const KURL::List& lst) { mURLsToImport = lst; if ( !lst.empty() ) importNextURLOrRedisplay(); } void CertManager::importNextURLOrRedisplay() { if ( !mURLsToImport.empty() ) { // We can only import them one by one, otherwise the jobs would run into each other KURL url = mURLsToImport.front(); mURLsToImport.pop_front(); slotImportCertFromFile( url ); } else { if ( isRemote() ) return; startKeyListing( false, true, mPreviouslySelectedFingerprints ); } } void CertManager::slotStartWatchGnuPG() { KProcess certManagerProc; certManagerProc << "kwatchgnupg"; if( !certManagerProc.start( KProcess::DontCare ) ) KMessageBox::error( this, i18n( "Could not start GnuPG LogViewer (kwatchgnupg). " "Please check your installation!" ), i18n( "Kleopatra Error" ) ); } #include "certmanager.moc" diff --git a/certmanager.h b/certmanager.h index d9d4b8199..50e87712f 100644 --- a/certmanager.h +++ b/certmanager.h @@ -1,216 +1,216 @@ /* -*- mode: c++; c-basic-offset:4 -*- certmanager.h This file is part of Kleopatra, the KDE keymanager Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB Kleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Kleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifndef _CERTMANAGER_H_ #define _CERTMANAGER_H_ //#include #include #include #include #include #include #include #include namespace Kleo { class KeyListView; class KeyListViewItem; class ProgressBar; class Job; } namespace KIO { class Job; } class KProcess; class KToolBar; class KAction; class CRLView; class HierarchyAnalyser; class LineEditAction; class ComboAction; class KURL; class QFile; class QStringList; class QLabel; namespace GpgME { class ImportResult; class KeyListResult; class Error; class Key; } class KDE_EXPORT CertManager : public KMainWindow { Q_OBJECT public: CertManager( bool remote = false, const QString& query = QString::null, const QString& import=QString::null, QWidget * parent=0, const char * name=0, WFlags f=0 ); ~CertManager(); bool isRemote() const { return mRemote; } signals: void stopOperations(); void enableOperations( bool ); private slots: void slotStartCertificateDownload( const QString & fingerprint, const QString& displayName ); void newCertificate(); void revokeCertificate(); void extendCertificate(); void slotDeleteCertificate(); void slotExportSecretKey(); void slotExportCertificate(); void slotUploadResult( KIO::Job* job ); void slotImportCertFromFile(); void slotImportCertFromFile( const KURL & filename ); void slotImportResult( KIO::Job* ); void slotCertificateImportResult( const GpgME::ImportResult & result ); void slotCertificateDownloadResult( const GpgME::Error & error, const QByteArray & keyData ); void slotKeyListResult( const GpgME::KeyListResult & result ); void slotDeleteResult( const GpgME::Error & error, const GpgME::Key & ); void slotSecretKeyExportResult( const GpgME::Error & error, const QByteArray & keyData ); void slotCertificateExportResult( const GpgME::Error & error, const QByteArray & keyData ); void slotClearCRLsResult(); void importCRLFromFile(); void importCRLFromLDAP(); void slotImportCRLJobFinished( KIO::Job * ); void slotDirmngrExited(); void slotStderr( KProcess*, char*, int ); void slotToggleRemote(int idx); void slotToggleHierarchicalView( bool ); void slotViewCRLs(); void slotClearCRLs(); void slotViewDetails(); void slotViewDetails( Kleo::KeyListViewItem * item ); void slotSelectionChanged(); void slotDownloadCertificate(); void slotStartWatchGnuPG(); void slotEditKeybindings(); void slotShowConfigurationDialog(); void slotConfigureGpgME(); void slotContextMenu(Kleo::KeyListViewItem*, const QPoint& point); void slotDropped(const KURL::List&); /** Schedule a repaint for the listview items. E.g. when the colour config has changed */ void slotRepaint(); /** Schedule a validating keylisting for the selected items (or all items, if none is selected). */ void slotValidate() { startRedisplay( true ); } /** Schedule a non-validating keylisting for the selected items (or all items, if none are selected). */ void slotRedisplay() { startRedisplay( false ); } /** Start a keylisting with the current value of the query text as pattern. */ void slotSearch(); void slotExpandAll(); void slotCollapseAll(); void slotRefreshKeys(); void slotRefreshKeysResult( const GpgME::Error & ); private: void createStatusBar(); void createActions(); void updateStatusBarLabels(); void updateImportActions( bool enable ); void startKeyListing( bool, bool, const QStringList & ); void startKeyListing( bool, bool, const std::set & ); void startCertificateImport( const QByteArray & keyData, const QString& certDisplayName ); void startImportCRL( const QString& fileName, bool isTempFile ); void startClearCRLs(); void startSecretKeyExport( const QString & fingerprint ); void startCertificateExport( const QStringList & fingerprints ); bool connectAndStartDirmngr( const char*, const char* ); void connectJobToStatusBarProgress( Kleo::Job * job, const QString & initialText ); void disconnectJobFromStatusBarProgress( const GpgME::Error & err ); void importNextURLOrRedisplay(); void startRedisplay( bool validating ); QString displayNameForJob( const Kleo::Job *job ); void readConfig(); void writeConfig(); private: Kleo::KeyListView * mKeyListView; CRLView * mCrlView; Kleo::ProgressBar * mProgressBar; QLabel * mStatusLabel; KProcess * mDirmngrProc; QString mErrorbuffer; QPtrList mItemsToDelete; KURL::List mURLsToImport; typedef QMap JobsDisplayNameMap; JobsDisplayNameMap mJobsDisplayNameMap; HierarchyAnalyser * mHierarchyAnalyser; LineEditAction * mLineEditAction; ComboAction * mComboAction; KAction * mFindAction; KAction * mImportCertFromFileAction; KAction * mImportCRLFromFileAction; KAction * mExportCertificateAction; KAction * mViewCertDetailsAction; KAction * mDeleteCertificateAction; #ifdef NOT_IMPLEMENTED_ANYWAY KAction * mRevokeCertificateAction; KAction * mExtendCertificateAction; #endif KAction * mExportSecretKeyAction; KAction * mDownloadCertificateAction; KAction * mValidateCertificateAction; QString mImportCRLTempFile; QString mCurrentQuery; std::set mPreviouslySelectedFingerprints; bool mNextFindRemote : 1; // state of the combo, i.e. whether the next find action will be remote bool mRemote : 1; // whether the currently displayed items are from a remote listing bool mDirMngrFound : 1; }; #endif // _CERTMANAGER_H_ diff --git a/conf/appearanceconfigpage.cpp b/conf/appearanceconfigpage.cpp new file mode 100644 index 000000000..5d2a434cc --- /dev/null +++ b/conf/appearanceconfigpage.cpp @@ -0,0 +1,87 @@ +/* + appearanceconfigpage.cpp + + This file is part of kleopatra, the KDE key manager + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#include "appearanceconfigpage.h" +#include +#include "appearanceconfigwidget.h" +#include +#include +#include + +#include + +AppearanceConfigurationPage::AppearanceConfigurationPage( QWidget * parent, const char * name ) + : KCModule( parent, name ) +{ + QVBoxLayout* lay = new QVBoxLayout( this ); + mWidget = new Kleo::AppearanceConfigWidget( this ); + lay->addWidget( mWidget ); + connect( mWidget, SIGNAL( changed() ), this, SLOT( slotChanged() ) ); + +#ifndef HAVE_UNBROKEN_KCMULTIDIALOG + load(); +#endif +} + + +void AppearanceConfigurationPage::load() +{ + mWidget->load(); +} + +void AppearanceConfigurationPage::save() +{ + mWidget->save(); + +} + +void AppearanceConfigurationPage::defaults() +{ + mWidget->defaults(); +} + +extern "C" +{ + KDE_EXPORT KCModule *create_kleopatra_config_appear( QWidget *parent, const char * ) + { + AppearanceConfigurationPage *page = + new AppearanceConfigurationPage( parent, "kleopatra_config_appear" ); + return page; + } +} + +// kdelibs-3.2 didn't have the changed signal in KCModule... +void AppearanceConfigurationPage::slotChanged() +{ + emit changed(true); +} + +#include "appearanceconfigpage.moc" diff --git a/lib/ui/cryptoconfigmodule.h b/conf/appearanceconfigpage.h similarity index 55% copy from lib/ui/cryptoconfigmodule.h copy to conf/appearanceconfigpage.h index df01d5d8a..c3acea007 100644 --- a/lib/ui/cryptoconfigmodule.h +++ b/conf/appearanceconfigpage.h @@ -1,68 +1,60 @@ /* - cryptoconfigmodule.h + appearanceconfigpage.h - This file is part of libkleopatra - Copyright (c) 2004,2005 Klarälvdalens Datakonsult AB + This file is part of kleopatra, the KDE key manager + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2, as published by the Free Software Foundation. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#ifndef CRYPTOCONFIGMODULE_H -#define CRYPTOCONFIGMODULE_H +#ifndef _APPEARANCE_CONFIGURE_PAGE_H_ +#define _APPEARANCE_CONFIGURE_PAGE_H_ -#include - -#include +#include namespace Kleo { + class AppearanceConfigWidget; +} - class CryptoConfig; - class CryptoConfigComponentGUI; - - /** - * Crypto Config Module widget, dynamically generated from CryptoConfig - * It's a simple QWidget so that it can be embedded into a dialog or into a KCModule. - */ - class CryptoConfigModule : public KJanusWidget { - Q_OBJECT - public: - CryptoConfigModule( Kleo::CryptoConfig* config, QWidget * parent=0, const char * name=0 ); - - void save(); - void reset(); // i.e. reload current settings, discarding user input - void defaults(); - void cancel(); +/** + * "Appearance" configuration page for kleopatra's configuration dialog + */ +class AppearanceConfigurationPage : public KCModule { + Q_OBJECT +public: + AppearanceConfigurationPage( QWidget * parent=0, const char * name=0 ); - signals: - void changed(); + virtual void load(); + virtual void save(); + virtual void defaults(); - private: - Kleo::CryptoConfig* mConfig; - QValueList mComponentGUIs; - }; +private slots: + void slotChanged(); -} +private: + Kleo::AppearanceConfigWidget* mWidget; +}; -#endif +#endif // _APPEARANCE_CONFIGURE_DIALOG_PRIVATE_H_ diff --git a/conf/appearanceconfigwidget.cpp b/conf/appearanceconfigwidget.cpp new file mode 100644 index 000000000..a3d177c2a --- /dev/null +++ b/conf/appearanceconfigwidget.cpp @@ -0,0 +1,358 @@ +/* + appearanceconfigwidget.cpp + + This file is part of kleopatra, the KDE key manager + Copyright (c) 2002,2004 Klarälvdalens Datakonsult AB + Copyright (c) 2002,2003 Marc Mutz + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "appearanceconfigwidget.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace Kleo; + +class CategoryListViewItem : public QListViewItem +{ +public: + CategoryListViewItem( QListView* lv, QListViewItem* prev, const KConfigBase& config ) + : QListViewItem( lv, prev ) { + + setName( config.readEntry( "Name", i18n("") ) ); + mForegroundColor = config.readColorEntry( "foreground-color" ); + mBackgroundColor = config.readColorEntry( "background-color" ); + mHasFont = config.hasKey( "font" ); + if ( mHasFont ) { + setFont( config.readFontEntry( "font" ) ); // sets mItalic and mBold + } + else { + mItalic = config.readBoolEntry( "font-italic", false ); + mBold = config.readBoolEntry( "font-bold", false ); + } + mStrikeOut = config.readBoolEntry( "font-strikeout", false ); + mIsExpired = config.readBoolEntry( "is-expired", false ); + mDirty = false; + } + + void save( KConfigBase& config ) { + config.writeEntry( "Name", text( 0 ) ); + config.writeEntry( "foreground-color", mForegroundColor ); + config.writeEntry( "background-color", mBackgroundColor ); + if ( mHasFont ) + config.writeEntry( "font", mFont ); + else { + config.deleteEntry( "font" ); + config.writeEntry( "font-italic", mItalic ); + config.writeEntry( "font-bold", mBold ); + } + config.writeEntry( "font-strikeout", mStrikeOut ); + } + + void setForegroundColor( const QColor& foreground ) { mForegroundColor = foreground; mDirty = true; } + void setBackgroundColor( const QColor& background ) { mBackgroundColor = background; mDirty = true; } + void setFont( const QFont& font ) { + mFont = font; + mHasFont = true; + mItalic = font.italic(); + mBold = font.bold(); + mDirty = true; + } + + QColor foregroundColor() const { return mForegroundColor; } + QColor backgroundColor() const { return mBackgroundColor; } + QFont font() const { return mFont; } + + void setDefaultAppearance() { + mForegroundColor = mIsExpired ? Qt::red : QColor(); + mBackgroundColor = QColor(); + mHasFont = false; + mFont = QFont(); + mBold = false; + mItalic = false; + mStrikeOut = false; + mDirty = true; + } + + bool isDirty() const { return mDirty; } + bool isItalic() const { return mItalic; } + bool isBold() const { return mBold; } + bool isStrikeout() const { return mStrikeOut; } + bool hasFont() const { return mHasFont; } + + void toggleItalic() { mItalic = !mItalic; if ( mHasFont ) mFont.setItalic( mItalic ); mDirty = true; } + void toggleBold() { mBold = !mBold; if ( mHasFont ) mFont.setBold( mBold ); mDirty = true; } + void toggleStrikeout() { mStrikeOut = !mStrikeOut; mDirty = true; } + +private: + void setName( const QString& name ) { + setText( 0, name ); + } + + void paintCell( QPainter * p, const QColorGroup & cg, int column, int width, int alignment ); + +private: + QColor mForegroundColor, mBackgroundColor; + QFont mFont; + bool mHasFont; + bool mIsExpired; // used for default settings + bool mItalic; + bool mBold; + bool mStrikeOut; + bool mDirty; +}; + +void CategoryListViewItem::paintCell( QPainter * p, const QColorGroup & cg, int column, int width, int alignment ) { + QColorGroup _cg = cg; + QFont font = p->font(); + if ( mHasFont ) + font = mFont; + else { + if ( mItalic ) + font.setItalic( true ); + if ( mBold ) + font.setBold( true ); + } + if ( mStrikeOut ) + font.setStrikeOut( true ); + p->setFont( font ); + + if ( mForegroundColor.isValid() ) + _cg.setColor( QColorGroup::Text, mForegroundColor ); + if ( mBackgroundColor.isValid() ) + _cg.setColor( QColorGroup::Base, mBackgroundColor ); + + QListViewItem::paintCell( p, _cg, column, width, alignment ); +} + +//// + +Kleo::AppearanceConfigWidget::AppearanceConfigWidget ( + QWidget* parent, const char* name, WFlags fl ) + : AppearanceConfigWidgetBase( parent, name, fl ) +{ + categoriesLV->setSorting( -1 ); + load(); +} + + +/* + * Destroys the object and frees any allocated resources + */ + +AppearanceConfigWidget::~AppearanceConfigWidget() +{ + // no need to delete child widgets, Qt does it all for us +} + + +void AppearanceConfigWidget::slotSelectionChanged( QListViewItem* item ) +{ + bool sel = item != 0; + foregroundButton->setEnabled( sel ); + backgroundButton->setEnabled( sel ); + fontButton->setEnabled( sel ); + italicCB->setEnabled( item ); + boldCB->setEnabled( item ); + strikeoutCB->setEnabled( item ); + defaultLookPB->setEnabled( sel ); + if ( item ) { + CategoryListViewItem* clvi = static_cast( item ); + italicCB->setChecked( clvi->isItalic() ); + boldCB->setChecked( clvi->isBold() ); + strikeoutCB->setChecked( clvi->isStrikeout() ); + } else { + italicCB->setChecked( false ); + boldCB->setChecked( false ); + strikeoutCB->setChecked( false ); + } +} + +/* + * set default appearance for selected category + */ +void AppearanceConfigWidget::slotDefaultClicked() +{ + CategoryListViewItem* item = static_cast(categoriesLV->selectedItem() ); + if ( !item ) + return; + item->setDefaultAppearance(); + item->repaint(); + slotSelectionChanged( item ); + emit changed(); +} + +void AppearanceConfigWidget::load() +{ + categoriesLV->clear(); + KConfig * config = Kleo::CryptoBackendFactory::instance()->configObject(); + if ( !config ) + return; + QStringList groups = config->groupList().grep( QRegExp( "^Key Filter #\\d+$" ) ); + for ( QStringList::const_iterator it = groups.begin() ; it != groups.end() ; ++it ) { + KConfigGroup cfg( config, *it ); + (void) new CategoryListViewItem( categoriesLV, categoriesLV->lastItem(), cfg ); + } +} + +void AppearanceConfigWidget::save() +{ + KConfig * config = Kleo::CryptoBackendFactory::instance()->configObject(); + if ( !config ) + return; + // We know (assume) that the groups in the config object haven't changed, + // so we just iterate over them and over the listviewitems, and map one-to-one. + QStringList groups = config->groupList().grep( QRegExp( "^Key Filter #\\d+$" ) ); + if ( groups.isEmpty() ) { + // If we created the default categories ourselves just now, then we need to make up their list + QListViewItemIterator lvit( categoriesLV ); + for ( ; lvit.current() ; ++lvit ) + groups << lvit.current()->text( 0 ); + } + + QListViewItemIterator lvit( categoriesLV ); + for ( QStringList::const_iterator it = groups.begin() ; it != groups.end() && lvit.current(); ++it, ++lvit ) { + CategoryListViewItem* item = static_cast(lvit.current() ); + KConfigGroup cfg( config, *it ); + item->save( cfg ); + } + config->sync(); + Kleo::KeyFilterManager::instance()->reload(); +} + + +void AppearanceConfigWidget::slotForegroundClicked() { + CategoryListViewItem* item = static_cast(categoriesLV->selectedItem() ); + Q_ASSERT( item ); + if( !item ) + return; + QColor fg = item->foregroundColor(); + int result = KColorDialog::getColor( fg ); + if ( result == KColorDialog::Accepted ) { + item->setForegroundColor( fg ); + item->repaint(); + emit changed(); + } +} + +void AppearanceConfigWidget::slotBackgroundClicked() { + CategoryListViewItem* item = static_cast(categoriesLV->selectedItem() ); + Q_ASSERT( item ); + if( !item ) + return; + QColor bg = item->backgroundColor(); + int result = KColorDialog::getColor( bg ); + if ( result == KColorDialog::Accepted ) { + item->setBackgroundColor( bg ); + item->repaint(); + emit changed(); + } +} + +void AppearanceConfigWidget::slotFontClicked() { + CategoryListViewItem* item = static_cast(categoriesLV->selectedItem() ); + Q_ASSERT( item ); + if( !item ) + return; + QFont font = item->font(); + int result = KFontDialog::getFont( font ); + if ( result == KFontDialog::Accepted ) { + item->setFont( font ); + item->repaint(); + emit changed(); + } +} + +void AppearanceConfigWidget::defaults() +{ + // This simply means "default look for every category" + QListViewItemIterator lvit( categoriesLV ); + for ( ; lvit.current() ; ++lvit ) { + CategoryListViewItem* item = static_cast( lvit.current() ); + item->setDefaultAppearance(); + item->repaint(); + } + emit changed(); +} + +void AppearanceConfigWidget::slotItalicClicked() +{ + CategoryListViewItem* item = static_cast(categoriesLV->selectedItem() ); + if ( item ) { + item->toggleItalic(); + item->repaint(); + emit changed(); + } +} + +void AppearanceConfigWidget::slotBoldClicked() +{ + CategoryListViewItem* item = static_cast(categoriesLV->selectedItem() ); + if ( item ) { + item->toggleBold(); + item->repaint(); + emit changed(); + } +} + +void AppearanceConfigWidget::slotStrikeoutClicked() +{ + CategoryListViewItem* item = static_cast(categoriesLV->selectedItem() ); + if ( item ) { + item->toggleStrikeout(); + item->repaint(); + emit changed(); + } +} + +#include "appearanceconfigwidget.moc" diff --git a/lib/backends/chiasmus/chiasmuslibrary.h b/conf/appearanceconfigwidget.h similarity index 53% copy from lib/backends/chiasmus/chiasmuslibrary.h copy to conf/appearanceconfigwidget.h index 1759b4fc7..dc5c79766 100644 --- a/lib/backends/chiasmus/chiasmuslibrary.h +++ b/conf/appearanceconfigwidget.h @@ -1,68 +1,73 @@ -/* -*- mode: C++; c-file-style: "gnu" -*- - chiasmuslibrary.h +/* + appearanceconfigwidget.h - This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + This file is part of kleopatra, the KDE key manager + Copyright (c) 2002,2004 Klarälvdalens Datakonsult AB + Copyright (c) 2002,2003 Marc Mutz Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. -*/ + */ +#ifndef APPEARANCECONFIGWIDGET_H +#define APPEARANCECONFIGWIDGET_H -#ifndef __KLEO_CHIASMUSLIBRARY_H__ -#define __KLEO_CHIASMUSLIBRARY_H__ - -#include -#include - -class KLibrary; +#include "appearanceconfigwidgetbase.h" +#include +class KConfig; namespace Kleo { - /** - @short small helper class to load xia.o through xia.so and make - the functionality available. - */ - class ChiasmusLibrary { - ChiasmusLibrary(); - ~ChiasmusLibrary(); - public: - static const ChiasmusLibrary * instance(); - static void deleteInstance(); - - int perform( const QValueVector & args ) const; - private: - typedef int ( *main_func )( int, char** ); - main_func chiasmus( QString * reason=0 ) const; + class AppearanceConfigWidget : public AppearanceConfigWidgetBase { + Q_OBJECT - private: - static ChiasmusLibrary * self; - mutable KLibrary * mXiaLibrary; + public: + AppearanceConfigWidget( + QWidget * parent=0, const char * name=0, WFlags f=0 ); + ~AppearanceConfigWidget(); + + void load(); + void save(); + + public slots: + void defaults(); + + signals: + void changed(); + + protected slots: + // reimplemented from the base class + virtual void slotDefaultClicked(); + virtual void slotSelectionChanged( QListViewItem * ); + virtual void slotForegroundClicked(); + virtual void slotBackgroundClicked(); + virtual void slotFontClicked(); + virtual void slotItalicClicked(); + virtual void slotBoldClicked(); + virtual void slotStrikeoutClicked(); }; - } - -#endif // __KLEO_CHIASMUSLIBRARY_H__ +#endif // APPEARANCECONFIGWIDGET_H diff --git a/conf/configuredialog.cpp b/conf/configuredialog.cpp new file mode 100644 index 000000000..87976f106 --- /dev/null +++ b/conf/configuredialog.cpp @@ -0,0 +1,73 @@ +/* + configuredialog.cpp + + This file is part of kleopatra + Copyright (C) 2000 Espen Sand, espen@kde.org + Copyright (C) 2001-2002 Marc Mutz + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#include "configuredialog.h" + +#include +#include +#include +#include + +ConfigureDialog::ConfigureDialog( QWidget *parent, const char *name, bool modal ) + : KCMultiDialog( KDialogBase::IconList, i18n( "Configure" ), parent, name, modal ) +{ + KWin::setIcons( winId(), kapp->icon(), kapp->miniIcon() ); + showButton( User1, true ); + + addModule( "kleopatra_config_dirserv", false ); + addModule( "kleopatra_config_appear", false ); + addModule( "kleopatra_config_dnorder", false ); + + // We store the size of the dialog on hide, because otherwise + // the KCMultiDialog starts with the size of the first kcm, not + // the largest one. This way at least after the first showing of + // the largest kcm the size is kept. + const KConfigGroup geometry( KGlobal::config(), "Geometry" ); + const int width = geometry.readNumEntry( "ConfigureDialogWidth" ); + const int height = geometry.readNumEntry( "ConfigureDialogHeight" ); + if ( width != 0 && height != 0 ) { + setMinimumSize( width, height ); + } + +} + +void ConfigureDialog::hideEvent( QHideEvent * ) { + KConfigGroup geometry( KGlobal::config(), "Geometry" ); + geometry.writeEntry( "ConfigureDialogWidth", width() ); + geometry.writeEntry( "ConfigureDialogHeight",height() ); +} + +ConfigureDialog::~ConfigureDialog() { +} + +#include "configuredialog.moc" diff --git a/lib/kleo/cryptobackend.cpp b/conf/configuredialog.h similarity index 59% copy from lib/kleo/cryptobackend.cpp copy to conf/configuredialog.h index 6da71bc9e..40b7e371b 100644 --- a/lib/kleo/cryptobackend.cpp +++ b/conf/configuredialog.h @@ -1,36 +1,52 @@ /* - kleo/cryptobackend.cpp + configuredialog.cpp - This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + This file is part of kleopatra + Copyright (C) 2000 Espen Sand, espen@kde.org + Copyright (C) 2001-2002 Marc Mutz + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. + modify it under the terms of the GNU General Public License, + version 2, as published by the Free Software Foundation. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#include "cryptobackend.h" +#ifndef _CONFIGURE_DIALOG_H_ +#define _CONFIGURE_DIALOG_H_ -const char Kleo::CryptoBackend::OpenPGP[] = "OpenPGP"; -const char Kleo::CryptoBackend::SMIME[] = "SMIME"; +#include + +class ConfigureDialog : public KCMultiDialog +{ + Q_OBJECT + +public: + ConfigureDialog( QWidget *parent=0, const char *name=0, bool modal=true ); + ~ConfigureDialog(); + +protected: + void hideEvent( QHideEvent *i ); + +}; + +#endif diff --git a/conf/dirservconfigpage.cpp b/conf/dirservconfigpage.cpp new file mode 100644 index 000000000..30b21005d --- /dev/null +++ b/conf/dirservconfigpage.cpp @@ -0,0 +1,291 @@ +/* + dirservconfigpage.cpp + + This file is part of kleopatra + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#include "dirservconfigpage.h" +#include "directoryserviceswidget.h" + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +// For sync'ing kabldaprc +class KABSynchronizer +{ +public: + KABSynchronizer() + : mConfig( "kabldaprc" ) { + mConfig.setGroup( "LDAP" ); + } + + KURL::List readCurrentList() const { + + KURL::List lst; + // stolen from kabc/ldapclient.cpp + const uint numHosts = mConfig.readUnsignedNumEntry( "NumSelectedHosts" ); + for ( uint j = 0; j < numHosts; j++ ) { + const QString num = QString::number( j ); + + KURL url; + url.setProtocol( "ldap" ); + url.setPath( "/" ); // workaround KURL parsing bug + const QString host = mConfig.readEntry( QString( "SelectedHost" ) + num ).stripWhiteSpace(); + url.setHost( host ); + + const int port = mConfig.readUnsignedNumEntry( QString( "SelectedPort" ) + num ); + if ( port != 0 ) + url.setPort( port ); + + const QString base = mConfig.readEntry( QString( "SelectedBase" ) + num ).stripWhiteSpace(); + url.setQuery( base ); + + const QString bindDN = mConfig.readEntry( QString( "SelectedBind" ) + num ).stripWhiteSpace(); + url.setUser( bindDN ); + + const QString pwdBindDN = mConfig.readEntry( QString( "SelectedPwdBind" ) + num ).stripWhiteSpace(); + url.setPass( pwdBindDN ); + lst.append( url ); + } + return lst; + } + + void writeList( const KURL::List& lst ) { + + mConfig.writeEntry( "NumSelectedHosts", lst.count() ); + + KURL::List::const_iterator it = lst.begin(); + KURL::List::const_iterator end = lst.end(); + unsigned j = 0; + for( ; it != end; ++it, ++j ) { + const QString num = QString::number( j ); + KURL url = *it; + + Q_ASSERT( url.protocol() == "ldap" ); + mConfig.writeEntry( QString( "SelectedHost" ) + num, url.host() ); + mConfig.writeEntry( QString( "SelectedPort" ) + num, url.port() ); + + // KURL automatically encoded the query (e.g. for spaces inside it), + // so decode it before writing it out + const QString base = KURL::decode_string( url.query().mid(1) ); + mConfig.writeEntry( QString( "SelectedBase" ) + num, base ); + mConfig.writeEntry( QString( "SelectedBind" ) + num, url.user() ); + mConfig.writeEntry( QString( "SelectedPwdBind" ) + num, url.pass() ); + } + mConfig.sync(); + } + +private: + KConfig mConfig; +}; + +static const char s_dirserv_componentName[] = "dirmngr"; +static const char s_dirserv_groupName[] = "LDAP"; +static const char s_dirserv_entryName[] = "LDAP Server"; + +static const char s_timeout_componentName[] = "dirmngr"; +static const char s_timeout_groupName[] = "LDAP"; +static const char s_timeout_entryName[] = "ldaptimeout"; + +static const char s_maxitems_componentName[] = "dirmngr"; +static const char s_maxitems_groupName[] = "LDAP"; +static const char s_maxitems_entryName[] = "max-replies"; + +static const char s_addnewservers_componentName[] = "dirmngr"; +static const char s_addnewservers_groupName[] = "LDAP"; +static const char s_addnewservers_entryName[] = "add-servers"; + +DirectoryServicesConfigurationPage::DirectoryServicesConfigurationPage( QWidget * parent, const char * name ) + : KCModule( parent, name ) +{ + mConfig = Kleo::CryptoBackendFactory::instance()->config(); + QVBoxLayout* lay = new QVBoxLayout( this, 0, KDialog::spacingHint() ); + Kleo::CryptoConfigEntry* entry = configEntry( s_dirserv_componentName, s_dirserv_groupName, s_dirserv_entryName, + Kleo::CryptoConfigEntry::ArgType_LDAPURL, true ); + mWidget = new Kleo::DirectoryServicesWidget( entry, this ); + lay->addWidget( mWidget ); + connect( mWidget, SIGNAL( changed() ), this, SLOT( slotChanged() ) ); + + // LDAP timeout + QHBox* box = new QHBox( this ); + box->setSpacing( KDialog::spacingHint() ); + lay->addWidget( box ); + QLabel* label = new QLabel( i18n( "LDAP &timeout (minutes:seconds)" ), box ); + mTimeout = new QTimeEdit( box ); + mTimeout->setDisplay( QTimeEdit::Minutes | QTimeEdit::Seconds ); + connect( mTimeout, SIGNAL( valueChanged( const QTime& ) ), this, SLOT( slotChanged() ) ); + label->setBuddy( mTimeout ); + QWidget* stretch = new QWidget( box ); + box->setStretchFactor( stretch, 2 ); + + // Max number of items returned by queries + box = new QHBox( this ); + box->setSpacing( KDialog::spacingHint() ); + lay->addWidget( box ); + mMaxItems = new KIntNumInput( box ); + mMaxItems->setLabel( i18n( "&Maximum number of items returned by query" ), Qt::AlignLeft | Qt::AlignVCenter ); + mMaxItems->setMinValue( 0 ); + connect( mMaxItems, SIGNAL( valueChanged(int) ), this, SLOT( slotChanged() ) ); + stretch = new QWidget( box ); + box->setStretchFactor( stretch, 2 ); + +#ifdef NOT_USEFUL_CURRENTLY + mAddNewServersCB = new QCheckBox( i18n( "Automatically add &new servers discovered in CRL distribution points" ), this ); + connect( mAddNewServersCB, SIGNAL( clicked() ), this, SLOT( slotChanged() ) ); + lay->addWidget( mAddNewServersCB ); +#endif + +#ifndef HAVE_UNBROKEN_KCMULTIDIALOG + load(); +#endif +} + +void DirectoryServicesConfigurationPage::load() +{ + mWidget->load(); + + mTimeoutConfigEntry = configEntry( s_timeout_componentName, s_timeout_groupName, s_timeout_entryName, Kleo::CryptoConfigEntry::ArgType_UInt, false ); + if ( mTimeoutConfigEntry ) { + QTime time = QTime().addSecs( mTimeoutConfigEntry->uintValue() ); + //kdDebug() << "timeout:" << mTimeoutConfigEntry->uintValue() << " -> " << time << endl; + mTimeout->setTime( time ); + } + + mMaxItemsConfigEntry = configEntry( s_maxitems_componentName, s_maxitems_groupName, s_maxitems_entryName, Kleo::CryptoConfigEntry::ArgType_UInt, false ); + if ( mMaxItemsConfigEntry ) { + mMaxItems->blockSignals( true ); // KNumInput emits valueChanged from setValue! + mMaxItems->setValue( mMaxItemsConfigEntry->uintValue() ); + mMaxItems->blockSignals( false ); + } + +#ifdef NOT_USEFUL_CURRENTLY + mAddNewServersConfigEntry = configEntry( s_addnewservers_componentName, s_addnewservers_groupName, s_addnewservers_entryName, Kleo::CryptoConfigEntry::ArgType_None, false ); + if ( mAddNewServersConfigEntry ) { + mAddNewServersCB->setChecked( mAddNewServersConfigEntry->boolValue() ); + } +#endif +} + +void DirectoryServicesConfigurationPage::save() +{ + mWidget->save(); + + QTime time( mTimeout->time() ); + unsigned int timeout = time.minute() * 60 + time.second(); + if ( mTimeoutConfigEntry && mTimeoutConfigEntry->uintValue() != timeout ) + mTimeoutConfigEntry->setUIntValue( timeout ); + if ( mMaxItemsConfigEntry && mMaxItemsConfigEntry->uintValue() != (uint)mMaxItems->value() ) + mMaxItemsConfigEntry->setUIntValue( mMaxItems->value() ); +#ifdef NOT_USEFUL_CURRENTLY + if ( mAddNewServersConfigEntry && mAddNewServersConfigEntry->boolValue() != mAddNewServersCB->isChecked() ) + mAddNewServersConfigEntry->setBoolValue( mAddNewServersCB->isChecked() ); +#endif + + mConfig->sync( true ); + + // Also write the LDAP URLs to kabldaprc so that they are used by kaddressbook + KABSynchronizer sync; + const KURL::List toAdd = mWidget->urlList(); + KURL::List currentList = sync.readCurrentList(); + + KURL::List::const_iterator it = toAdd.begin(); + KURL::List::const_iterator end = toAdd.end(); + for( ; it != end; ++it ) { + // check if the URL is already in currentList + if ( currentList.find( *it ) == currentList.end() ) + // if not, add it + currentList.append( *it ); + } + sync.writeList( currentList ); +} + +void DirectoryServicesConfigurationPage::defaults() +{ + mWidget->defaults(); + if ( mTimeoutConfigEntry ) + mTimeoutConfigEntry->resetToDefault(); + if ( mMaxItemsConfigEntry ) + mMaxItemsConfigEntry->resetToDefault(); +#ifdef NOT_USEFUL_CURRENTLY + if ( mAddNewServersConfigEntry ) + mAddNewServersConfigEntry->resetToDefault(); +#endif + load(); +} + +extern "C" +{ + KDE_EXPORT KCModule *create_kleopatra_config_dirserv( QWidget *parent, const char * ) + { + DirectoryServicesConfigurationPage *page = + new DirectoryServicesConfigurationPage( parent, "kleopatra_config_dirserv" ); + return page; + } +} + +// kdelibs-3.2 didn't have the changed signal in KCModule... +void DirectoryServicesConfigurationPage::slotChanged() +{ + emit changed(true); +} + + +// Find config entry for ldap servers. Implements runtime checks on the configuration option. +Kleo::CryptoConfigEntry* DirectoryServicesConfigurationPage::configEntry( const char* componentName, + const char* groupName, + const char* entryName, + Kleo::CryptoConfigEntry::ArgType argType, + bool isList ) +{ + Kleo::CryptoConfigEntry* entry = mConfig->entry( componentName, groupName, entryName ); + if ( !entry ) { + KMessageBox::error( this, i18n( "Backend error: gpgconf does not seem to know the entry for %1/%2/%3" ).arg( componentName, groupName, entryName ) ); + return 0; + } + if( entry->argType() != argType || entry->isList() != isList ) { + KMessageBox::error( this, i18n( "Backend error: gpgconf has wrong type for %1/%2/%3: %4 %5" ).arg( componentName, groupName, entryName ).arg( entry->argType() ).arg( entry->isList() ) ); + return 0; + } + return entry; +} + +#include "dirservconfigpage.moc" diff --git a/conf/dirservconfigpage.h b/conf/dirservconfigpage.h new file mode 100644 index 000000000..8c7c75439 --- /dev/null +++ b/conf/dirservconfigpage.h @@ -0,0 +1,84 @@ +/* + dirservconfigpage.h + + This file is part of kleopatra + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifndef DIRSERVCONFIGPAGE_H +#define DIRSERVCONFIGPAGE_H + +#include +#include +#include + +class QCheckBox; +class QTimeEdit; +class KIntNumInput; +namespace Kleo { + class CryptoConfig; + class CryptoConfigEntry; + class DirectoryServicesWidget; +} + +/** + * "Directory Services" configuration page for kleopatra's configuration dialog + * The user can configure LDAP servers in this page, to be used for listing/fetching + * remote certificates in kleopatra. + */ +class KDE_EXPORT DirectoryServicesConfigurationPage : public KCModule { + Q_OBJECT +public: + DirectoryServicesConfigurationPage( QWidget * parent=0, const char * name=0 ); + + virtual void load(); + virtual void save(); + virtual void defaults(); + +private slots: + void slotChanged(); + +private: + Kleo::CryptoConfigEntry* configEntry( const char* componentName, + const char* groupName, + const char* entryName, + Kleo::CryptoConfigEntry::ArgType argType, + bool isList ); + + Kleo::DirectoryServicesWidget* mWidget; + QTimeEdit* mTimeout; + KIntNumInput* mMaxItems; + QCheckBox* mAddNewServersCB; + + Kleo::CryptoConfigEntry* mTimeoutConfigEntry; + Kleo::CryptoConfigEntry* mMaxItemsConfigEntry; + Kleo::CryptoConfigEntry* mAddNewServersConfigEntry; + + Kleo::CryptoConfig* mConfig; +}; + +#endif diff --git a/conf/dnorderconfigpage.cpp b/conf/dnorderconfigpage.cpp new file mode 100644 index 000000000..44b86b5b8 --- /dev/null +++ b/conf/dnorderconfigpage.cpp @@ -0,0 +1,77 @@ +/* + dnorderconfigpage.cpp + + This file is part of kleopatra, the KDE key manager + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#include "dnorderconfigpage.h" + +#include +#include + +#include + +#include + +DNOrderConfigPage::DNOrderConfigPage( QWidget * parent, const char * name ) + : KCModule( parent, name ) +{ + QVBoxLayout * vlay = new QVBoxLayout( this ); + mWidget = Kleo::DNAttributeMapper::instance()->configWidget( this, "mWidget" ); + vlay->addWidget( mWidget ); + + connect( mWidget, SIGNAL(changed()), SLOT(slotChanged()) ); + +#ifndef HAVE_UNBROKEN_KCMULTIDIALOG + load(); +#endif +} + + +void DNOrderConfigPage::load() { + mWidget->load(); +} + +void DNOrderConfigPage::save() { + mWidget->save(); +} + +void DNOrderConfigPage::defaults() { + mWidget->defaults(); +} + +// kdelibs-3.2 didn't have the changed signal in KCModule... +void DNOrderConfigPage::slotChanged() { + emit changed(true); +} + +extern "C" KDE_EXPORT KCModule * create_kleopatra_config_dnorder( QWidget * parent, const char * ) { + return new DNOrderConfigPage( parent, "kleopatra_config_dnorder" ); +} + +#include "dnorderconfigpage.moc" diff --git a/lib/ui/cryptoconfigmodule.h b/conf/dnorderconfigpage.h similarity index 55% copy from lib/ui/cryptoconfigmodule.h copy to conf/dnorderconfigpage.h index df01d5d8a..c874c7527 100644 --- a/lib/ui/cryptoconfigmodule.h +++ b/conf/dnorderconfigpage.h @@ -1,68 +1,63 @@ /* - cryptoconfigmodule.h + dnorderconfigpage.h - This file is part of libkleopatra - Copyright (c) 2004,2005 Klarälvdalens Datakonsult AB + This file is part of kleopatra, the KDE key manager + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2, as published by the Free Software Foundation. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#ifndef CRYPTOCONFIGMODULE_H -#define CRYPTOCONFIGMODULE_H +#ifndef __KLEOPATRA_CONF_DNORDERCONFIGPAGE_H__ +#define __KLEOPATRA_CONF_DNORDERCONFIGPAGE_H__ -#include - -#include +#include namespace Kleo { - - class CryptoConfig; - class CryptoConfigComponentGUI; - - /** - * Crypto Config Module widget, dynamically generated from CryptoConfig - * It's a simple QWidget so that it can be embedded into a dialog or into a KCModule. - */ - class CryptoConfigModule : public KJanusWidget { - Q_OBJECT - public: - CryptoConfigModule( Kleo::CryptoConfig* config, QWidget * parent=0, const char * name=0 ); - - void save(); - void reset(); // i.e. reload current settings, discarding user input - void defaults(); - void cancel(); - - signals: - void changed(); - - private: - Kleo::CryptoConfig* mConfig; - QValueList mComponentGUIs; - }; - + class DNAttributeOrderConfigWidget; } -#endif +/** + * "DN Order" configuration page for kleopatra's configuration dialog + */ +class DNOrderConfigPage : public KCModule { + Q_OBJECT +public: + DNOrderConfigPage( QWidget * parent=0, const char * name=0 ); + + /*! reimplementation */ + void load(); + /*! reimplementation */ + void save(); + /*! reimplementation */ + void defaults(); + +private slots: + void slotChanged(); + +private: + Kleo::DNAttributeOrderConfigWidget * mWidget; +}; + +#endif // __KLEOPATRA_CONF_DNORDERCONFIGPAGE_H__ diff --git a/crlview.cpp b/crlview.cpp index dc743646f..6cf7ddeaa 100644 --- a/crlview.cpp +++ b/crlview.cpp @@ -1,78 +1,138 @@ -#include -#include -#include +/* + crlview.cpp + + This file is part of Kleopatra, the KDE keymanager + Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB + + Kleopatra is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + Kleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "crlview.h" #include #include #include #include #include +#include -#include "crlview.h" -#include "crlview.moc" +#include +#include +#include +#include +#include CRLView::CRLView( QWidget* parent, const char* name, bool modal ) : QDialog( parent, name, modal ), _process(0) { QVBoxLayout* topLayout = new QVBoxLayout( this, 10, 4 ); topLayout->addWidget( new QLabel( i18n("CRL cache dump:"), this ) ); - _textView = new QTextView( this ); - _textView->setWordWrap( QTextEdit::NoWrap ); + _textView = new QTextEdit( this ); + _textView->setFont( KGlobalSettings::fixedFont() ); + _textView->setTextFormat( QTextEdit::LogText ); topLayout->addWidget( _textView ); QHBoxLayout* hbLayout = new QHBoxLayout( topLayout ); _updateButton = new KPushButton( i18n("&Update"), this ); _closeButton = new KPushButton( KStdGuiItem::close(), this ); hbLayout->addWidget( _updateButton ); hbLayout->addStretch(); hbLayout->addWidget( _closeButton ); // connections: connect( _updateButton, SIGNAL( clicked() ), this, SLOT( slotUpdateView() ) ); connect( _closeButton, SIGNAL( clicked() ), this, SLOT( close() ) ); + + resize( _textView->fontMetrics().width( 'M' ) * 80, + _textView->fontMetrics().lineSpacing() * 25 ); + + _timer = new QTimer( this ); + connect( _timer, SIGNAL(timeout()), SLOT(slotAppendBuffer()) ); } CRLView::~CRLView() { - delete _process; + delete _process; _process = 0; +} + +void CRLView::closeEvent( QCloseEvent * e ) { + QDialog::closeEvent( e ); + delete _process; _process = 0; } void CRLView::slotUpdateView() { _updateButton->setEnabled( false ); _textView->clear(); + _buffer = QString::null; if( _process == 0 ) { _process = new KProcess(); - *_process << "dirmngr"; - *_process << "--list-crls"; + *_process << "gpgsm" << "--call-dirmngr" << "listcrls"; connect( _process, SIGNAL( receivedStdout( KProcess*, char*, int) ), this, SLOT( slotReadStdout( KProcess*, char*, int ) ) ); connect( _process, SIGNAL( processExited( KProcess* ) ), this, SLOT( slotProcessExited() ) ); } if( _process->isRunning() ) _process->kill(); if( !_process->start( KProcess::NotifyOnExit, KProcess::Stdout ) ) { - KMessageBox::error( this, i18n( "Unable to start dirmngr process. Please check your installation." ), i18n( "Certificate Manager Error" ) ); + KMessageBox::error( this, i18n( "Unable to start gpgsm process. Please check your installation." ), i18n( "Certificate Manager Error" ) ); slotProcessExited(); } + _timer->start( 1000 ); } void CRLView::slotReadStdout( KProcess*, char* buf, int len) { - _textView->append( QString::fromUtf8( buf, len ) ); + _buffer.append( QString::fromUtf8( buf, len ) ); +} + +void CRLView::slotAppendBuffer() { + _textView->append( _buffer ); + _buffer = QString::null; } void CRLView::slotProcessExited() { + _timer->stop(); + slotAppendBuffer(); _updateButton->setEnabled( true ); if( !_process->normalExit() ) { - KMessageBox::error( this, i18n( "The Dirmngr process ended prematurely because of an unexpected error." ), i18n( "Certificate Manager Error" ) ); + KMessageBox::error( this, i18n( "The GpgSM process ended prematurely because of an unexpected error." ), i18n( "Certificate Manager Error" ) ); } } + +#include "crlview.moc" diff --git a/crlview.h b/crlview.h index ac1016ae1..55828a90f 100644 --- a/crlview.h +++ b/crlview.h @@ -1,29 +1,69 @@ +/* + crlview.h + + This file is part of Kleopatra, the KDE keymanager + Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB + + Kleopatra is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + Kleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + #ifndef CRLVIEW_H #define CRLVIEW_H #include +#include -class QTextView; +class QTextEdit; class QPushButton; class KProcess; +class QTimer; class CRLView : public QDialog { Q_OBJECT public: CRLView( QWidget* parent = 0, const char* name = 0, bool modal = false ); ~CRLView(); public slots: void slotUpdateView(); protected slots: void slotReadStdout( KProcess*, char* buf, int len); void slotProcessExited(); + void slotAppendBuffer(); + +protected: + void closeEvent( QCloseEvent * ); private: - QTextView* _textView; + QTextEdit* _textView; QPushButton* _updateButton; QPushButton* _closeButton; KProcess* _process; + QTimer* _timer; + QString _buffer; }; #endif // CRLVIEW_H diff --git a/customactions.cpp b/customactions.cpp new file mode 100644 index 000000000..6a48a4768 --- /dev/null +++ b/customactions.cpp @@ -0,0 +1,134 @@ +/* + customactions.cpp + + This file is part of Kleopatra, the KDE keymanager + Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB + + Kleopatra is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + Kleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#include "customactions.h" + +#include +#include + +#include +#include + + +LabelAction::LabelAction( const QString & text, KActionCollection * parent, + const char* name ) + : KAction( text, QIconSet(), KShortcut(), 0, 0, parent, name ) +{ + +} + +int LabelAction::plug( QWidget * widget, int index ) { + if ( kapp && !kapp->authorizeKAction( name() ) ) + return -1; + if ( widget->inherits( "KToolBar" ) ) { + KToolBar * bar = (KToolBar *)widget; + int id_ = getToolButtonID(); + QLabel* label = new QLabel( text(), bar, "kde toolbar widget" ); + bar->insertWidget( id_, label->width(), label, index ); + addContainer( bar, id_ ); + connect( bar, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) ); + return containerCount() - 1; + } + + return KAction::plug( widget, index ); +} + +LineEditAction::LineEditAction( const QString & text, KActionCollection * parent, + QObject * receiver, const char * member, const char * name ) + : KAction( text, QIconSet(), KShortcut(), 0, 0, parent, name ), + _le(0), _receiver(receiver), _member(member) +{ + +} + +int LineEditAction::plug( QWidget * widget, int index ) { + if ( kapp && !kapp->authorizeKAction( name() ) ) + return -1; + if ( widget->inherits( "KToolBar" ) ) { + KToolBar *bar = (KToolBar *)widget; + int id_ = getToolButtonID(); + // The toolbar trick doesn't seem to work for lineedits + //_le = new QLineEdit( bar, "kde toolbar widget" ); + _le = new QLineEdit( bar ); + bar->insertWidget( id_, _le->width(), _le, index ); + bar->setStretchableWidget( _le ); + addContainer( bar, id_ ); + connect( bar, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) ); + connect( _le, SIGNAL( returnPressed() ), _receiver, _member ); + return containerCount() - 1; + } + + return KAction::plug( widget, index ); +} + +void LineEditAction::clear() { + _le->clear(); +} + +void LineEditAction::focusAll() { + _le->selectAll(); + _le->setFocus(); +} + +QString LineEditAction::text() const { + return _le->text(); +} + +void LineEditAction::setText( const QString & txt ) { + _le->setText(txt); +} + + +ComboAction::ComboAction( const QStringList & lst, KActionCollection * parent, + QObject * receiver, const char * member, const char * name ) + : KAction( QString::null, QIconSet(), KShortcut(), 0, 0, parent, name ), + _lst(lst), _receiver(receiver), _member(member) +{ + +} + +int ComboAction::plug( QWidget * widget, int index ) { + if ( kapp && !kapp->authorizeKAction( name() ) ) + return -1; + if ( widget->inherits( "KToolBar" ) ) { + KToolBar *bar = (KToolBar *)widget; + int id_ = getToolButtonID(); + bar->insertCombo( _lst, id_, false, SIGNAL( highlighted(int) ), _receiver, _member ); + addContainer( bar, id_ ); + connect( bar, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) ); + return containerCount() - 1; + } + + return KAction::plug( widget, index ); +} + +#include "customactions.moc" diff --git a/kwatchgnupg/aboutdata.cpp b/customactions.h similarity index 52% copy from kwatchgnupg/aboutdata.cpp copy to customactions.h index 68c918e9d..dfbaf5461 100644 --- a/kwatchgnupg/aboutdata.cpp +++ b/customactions.h @@ -1,73 +1,84 @@ /* - aboutdata.cpp + customactions.h This file is part of Kleopatra, the KDE keymanager - Copyright (c) 2004 Klar�vdalens Datakonsult AB + Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB Kleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Kleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#include "aboutdata.h" +#ifndef __CUSTOMACTIONS_H__ +#define __CUSTOMACTIONS_H__ -#include +#include -static const char kwatchgnupg_version[] = "1.0"; -static const char description[] = I18N_NOOP("GnuPG log viewer"); +#include -struct about_data { - const char * name; - const char * desc; - const char * email; - const char * web; +class QLineEdit; + +class LabelAction : public KAction { + Q_OBJECT +public: + LabelAction( const QString & text, KActionCollection * parent, + const char* name ); + + int plug( QWidget * widget, int index=-1 ); }; -static const about_data authors[] = { - { "Steffen Hansen", I18N_NOOP("Original Author"), "hansen@kde.org", 0 }, +class LineEditAction : public KAction { + Q_OBJECT +public: + LineEditAction( const QString & text, KActionCollection * parent, + QObject * receiver, const char * member, const char * name ); + + int plug( QWidget * widget, int index=-1 ); + void clear(); + void focusAll(); + QString text() const; + void setText( const QString & txt ); +private: + QLineEdit* _le; + QObject * _receiver; + const char * _member; }; -#if 0 -// can't create zero size array - doesn't compile -static const about_data credits[] = { - // PENDING(steffen) add stuff +class ComboAction : public KAction { + Q_OBJECT +public: + ComboAction( const QStringList & lst, KActionCollection * parent, + QObject * receiver, const char * member, const char * name ); + + int plug( QWidget * widget, int index=-1 ); + +private: + QStringList _lst; + QObject * _receiver; + const char * _member; }; -#endif - -AboutData::AboutData() - : KAboutData( "kwatchgnupg", I18N_NOOP("KWatchGnuPG"), - kwatchgnupg_version, description, License_GPL, - "(c) 2004 Klar\xC3\xA4lvdalens Datakonsult AB\n" ) -{ - using ::authors; - //using ::credits; - for ( unsigned int i = 0 ; i < sizeof authors / sizeof *authors ; ++i ) - addAuthor( authors[i].name, authors[i].desc, - authors[i].email, authors[i].web ); -#if 0 - for ( unsigned int i = 0 ; i < sizeof credits / sizeof *credits ; ++i ) - addCredit( credits[i].name, credits[i].desc, - credits[i].email, credits[i].web ); -#endif -} + + + +#endif // __CUSTOMACTIONS_H__ diff --git a/hierarchyanalyser.cpp b/hierarchyanalyser.cpp new file mode 100644 index 000000000..8e8c13803 --- /dev/null +++ b/hierarchyanalyser.cpp @@ -0,0 +1,81 @@ +/* + hierarchyanalyser.cpp + + This file is part of Kleopatra, the KDE keymanager + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Kleopatra is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + Kleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "hierarchyanalyser.h" + +#include +#include + +HierarchyAnalyser::HierarchyAnalyser( QObject * parent, const char * name ) + : QObject( parent, name ) +{ + +} + +HierarchyAnalyser::~HierarchyAnalyser() { + +} + +void HierarchyAnalyser::slotNextKey( const GpgME::Key & key ) { + if ( key.isNull() ) + return; + if ( key.isRoot() || !key.chainID() || !*key.chainID() ) + // root keys have themselves as issuer - we don't want them to + // have parents, though: + mSubjectsByIssuer[0].push_back( key ); + else + mSubjectsByIssuer[key.chainID()].push_back( key ); +} + +const std::vector & HierarchyAnalyser::subjectsForIssuer( const char * issuer_dn ) const { + static const std::vector empty; + std::map< QCString, std::vector >::const_iterator it = + mSubjectsByIssuer.find( issuer_dn ); + return it == mSubjectsByIssuer.end() ? empty : it->second ; +} + +std::vector HierarchyAnalyser::subjectsForIssuerRecursive( const char * issuer_dn ) const { + std::vector keys = subjectsForIssuer( issuer_dn ); + for ( unsigned int i = 0 ; i < keys.size() ; ++i ) // can't use iterators here, since appending would invalidate them + if ( const char * fpr = keys[i].primaryFingerprint() ) { + const std::vector & tmp = subjectsForIssuer( fpr ); + std::copy( tmp.begin(), tmp.end(), std::back_inserter( keys ) ); + } + return keys; +} + + +#include "hierarchyanalyser.moc" diff --git a/kwatchgnupg/aboutdata.cpp b/hierarchyanalyser.h similarity index 51% copy from kwatchgnupg/aboutdata.cpp copy to hierarchyanalyser.h index 68c918e9d..ccf07d4f3 100644 --- a/kwatchgnupg/aboutdata.cpp +++ b/hierarchyanalyser.h @@ -1,73 +1,66 @@ -/* - aboutdata.cpp +/* -*- mode: c++ -*- + hierarchyanalyser.h This file is part of Kleopatra, the KDE keymanager - Copyright (c) 2004 Klar�vdalens Datakonsult AB + Copyright (c) 2004 Klarälvdalens Datakonsult AB Kleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Kleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#include "aboutdata.h" +#ifndef __HIERARCHYANALYSER_H__ +#define __HIERARCHYANALYSER_H__ -#include +#include -static const char kwatchgnupg_version[] = "1.0"; -static const char description[] = I18N_NOOP("GnuPG log viewer"); +#include +#include -struct about_data { - const char * name; - const char * desc; - const char * email; - const char * web; -}; +#include +#include -static const about_data authors[] = { - { "Steffen Hansen", I18N_NOOP("Original Author"), "hansen@kde.org", 0 }, -}; +class HierarchyAnalyser : public QObject { + Q_OBJECT +public: + HierarchyAnalyser( QObject * parent=0, const char * name=0 ); + ~HierarchyAnalyser(); + + const std::vector & rootItems() const { + return subjectsForIssuer( 0 ); + } + const std::vector & subjectsForIssuer( const char * issuer_fpr ) const; + std::vector subjectsForIssuerRecursive( const char * issuer_fpr ) const; + + void clear() { mSubjectsByIssuer.clear(); } -#if 0 -// can't create zero size array - doesn't compile -static const about_data credits[] = { - // PENDING(steffen) add stuff +public slots: + void slotNextKey( const GpgME::Key & key ); + +private: + std::map< QCString, std::vector > mSubjectsByIssuer; }; -#endif - -AboutData::AboutData() - : KAboutData( "kwatchgnupg", I18N_NOOP("KWatchGnuPG"), - kwatchgnupg_version, description, License_GPL, - "(c) 2004 Klar\xC3\xA4lvdalens Datakonsult AB\n" ) -{ - using ::authors; - //using ::credits; - for ( unsigned int i = 0 ; i < sizeof authors / sizeof *authors ; ++i ) - addAuthor( authors[i].name, authors[i].desc, - authors[i].email, authors[i].web ); -#if 0 - for ( unsigned int i = 0 ; i < sizeof credits / sizeof *credits ; ++i ) - addCredit( credits[i].name, credits[i].desc, - credits[i].email, credits[i].web ); -#endif -} + + +#endif // __HIERARCHYANALYSER_H__ diff --git a/kwatchgnupg/aboutdata.cpp b/kwatchgnupg/aboutdata.cpp index 68c918e9d..4bde52190 100644 --- a/kwatchgnupg/aboutdata.cpp +++ b/kwatchgnupg/aboutdata.cpp @@ -1,73 +1,73 @@ /* aboutdata.cpp This file is part of Kleopatra, the KDE keymanager Copyright (c) 2004 Klar�vdalens Datakonsult AB Kleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Kleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #include "aboutdata.h" #include static const char kwatchgnupg_version[] = "1.0"; static const char description[] = I18N_NOOP("GnuPG log viewer"); struct about_data { const char * name; const char * desc; const char * email; const char * web; }; static const about_data authors[] = { { "Steffen Hansen", I18N_NOOP("Original Author"), "hansen@kde.org", 0 }, }; #if 0 // can't create zero size array - doesn't compile static const about_data credits[] = { // PENDING(steffen) add stuff }; #endif AboutData::AboutData() : KAboutData( "kwatchgnupg", I18N_NOOP("KWatchGnuPG"), kwatchgnupg_version, description, License_GPL, "(c) 2004 Klar\xC3\xA4lvdalens Datakonsult AB\n" ) { using ::authors; //using ::credits; for ( unsigned int i = 0 ; i < sizeof authors / sizeof *authors ; ++i ) addAuthor( authors[i].name, authors[i].desc, authors[i].email, authors[i].web ); #if 0 for ( unsigned int i = 0 ; i < sizeof credits / sizeof *credits ; ++i ) addCredit( credits[i].name, credits[i].desc, credits[i].email, credits[i].web ); #endif } diff --git a/lib/kleo/cryptobackend.cpp b/kwatchgnupg/aboutdata.h similarity index 58% copy from lib/kleo/cryptobackend.cpp copy to kwatchgnupg/aboutdata.h index 6da71bc9e..0e1f9f631 100644 --- a/lib/kleo/cryptobackend.cpp +++ b/kwatchgnupg/aboutdata.h @@ -1,36 +1,43 @@ /* - kleo/cryptobackend.cpp + aboutdata.h - This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + This file is part of Kleopatra, the KDE keymanager + Copyright (c) 2004 Klarälvdalens Datakonsult AB - Libkleopatra is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. + Kleopatra is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. - Libkleopatra is distributed in the hope that it will be useful, + Kleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#include "cryptobackend.h" +#ifndef ABOUTDATA_H +#define ABOUTDATA_H -const char Kleo::CryptoBackend::OpenPGP[] = "OpenPGP"; -const char Kleo::CryptoBackend::SMIME[] = "SMIME"; +#include + +class AboutData : public KAboutData { +public: + AboutData(); +}; + +#endif // ABOUTDATA_H diff --git a/kwatchgnupg/kwatchgnupgconfig.cpp b/kwatchgnupg/kwatchgnupgconfig.cpp new file mode 100644 index 000000000..b621e92b8 --- /dev/null +++ b/kwatchgnupg/kwatchgnupgconfig.cpp @@ -0,0 +1,206 @@ +/* + kwatchgnupgconfig.cpp + + This file is part of Kleopatra, the KDE keymanager + Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB + + Kleopatra is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + Kleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#include "kwatchgnupgconfig.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static const char* log_levels[] = { "none", "basic", "advanced", "expert", "guru" }; + +static int log_level_to_int( const QString& loglevel ) +{ + if( loglevel == "none" ) { + return 0; + } else if( loglevel == "basic" ) { + return 1; + } else if( loglevel == "advanced" ) { + return 2; + } else if( loglevel == "expert" ) { + return 3; + } else if( loglevel == "guru" ) { + return 4; + } else { + // default + return 1; + } +} + +KWatchGnuPGConfig::KWatchGnuPGConfig( QWidget* parent, const char* name ) + : KDialogBase( Plain, i18n("Configure KWatchGnuPG"), + Ok|Cancel, Ok, parent, name ) +{ + // tmp vars: + QWidget * w; + QGridLayout * glay; + QGroupBox * group; + + QWidget * top = plainPage(); + + QVBoxLayout * vlay = new QVBoxLayout( top, 0, spacingHint() ); + + group = new QVGroupBox( i18n("WatchGnuPG"), top ); + group->layout()->setSpacing( spacingHint() ); + + w = new QWidget( group ); + + glay = new QGridLayout( w, 3, 2, 0, spacingHint() ); + glay->setColStretch( 1, 1 ); + + int row = -1; + + ++row; + mExeED = new KURLRequester( w ); + glay->addWidget( new QLabel( mExeED, i18n("&Executable:"), w ), row, 0 ); + glay->addWidget( mExeED, row, 1 ); + connect( mExeED, SIGNAL(textChanged(const QString&)), SLOT(slotChanged()) ); + + ++row; + mSocketED = new KURLRequester( w ); + glay->addWidget( new QLabel( mSocketED, i18n("&Socket:"), w ), row, 0 ); + glay->addWidget( mSocketED, row, 1 ); + connect( mSocketED, SIGNAL(textChanged(const QString&)), SLOT(slotChanged()) ); + + ++row; + mLogLevelCB = new QComboBox( false, w ); + mLogLevelCB->insertItem( i18n("None") ); + mLogLevelCB->insertItem( i18n("Basic") ); + mLogLevelCB->insertItem( i18n("Advanced") ); + mLogLevelCB->insertItem( i18n("Expert") ); + mLogLevelCB->insertItem( i18n("Guru") ); + glay->addWidget( new QLabel( mLogLevelCB, i18n("Default &log level:"), w ), row, 0 ); + glay->addWidget( mLogLevelCB, row, 1 ); + connect( mLogLevelCB, SIGNAL(activated(int)), SLOT(slotChanged()) ); + + vlay->addWidget( group ); + + /******************* Log Window group *******************/ + group = new QVGroupBox( i18n("Log Window"), top ); + group->layout()->setSpacing( spacingHint() ); + + w = new QWidget( group ); + + glay = new QGridLayout( w, 2, 3, 0, spacingHint() ); + glay->setColStretch( 1, 1 ); + + row = -1; + + ++row; + mLoglenSB = new QSpinBox( 0, 1000000, 100, w ); + mLoglenSB->setSuffix( i18n("history size spinbox suffix"," lines") ); + mLoglenSB->setSpecialValueText( i18n("unlimited") ); + glay->addWidget( new QLabel( mLoglenSB, i18n("&History size:"), w ), row, 0 ); + glay->addWidget( mLoglenSB, row, 1 ); + QPushButton * button = new QPushButton( i18n("Set &Unlimited"), w ); + glay->addWidget( button, row, 2 ); + + connect( mLoglenSB, SIGNAL(valueChanged(int)), SLOT(slotChanged()) ); + connect( button, SIGNAL(clicked()), SLOT(slotSetHistorySizeUnlimited()) ); + + ++row; + mWordWrapCB = new QCheckBox( i18n("Enable &word wrapping"), w ); + mWordWrapCB->hide(); // QTextEdit doesn't support word wrapping in LogText mode + glay->addMultiCellWidget( mWordWrapCB, row, row, 0, 2 ); + + connect( mWordWrapCB, SIGNAL(clicked()), SLOT(slotChanged()) ); + + vlay->addWidget( group ); + vlay->addStretch( 1 ); + + connect( this, SIGNAL(applyClicked()), SLOT(slotSave()) ); + connect( this, SIGNAL(okClicked()), SLOT(slotSave()) ); +} + +void KWatchGnuPGConfig::slotSetHistorySizeUnlimited() { + mLoglenSB->setValue( 0 ); +} + +void KWatchGnuPGConfig::loadConfig() +{ + KConfig* config = kapp->config(); + config->setGroup("WatchGnuPG"); + mExeED->setURL( config->readEntry( "Executable", "watchgnupg" ) ); + mSocketED->setURL( config->readEntry( "Socket", QDir::home().canonicalPath() + + "/.gnupg/log-socket") ); + mLogLevelCB->setCurrentItem( log_level_to_int( config->readEntry( "LogLevel", "basic" ) ) ); + + config->setGroup("LogWindow"); + mLoglenSB->setValue( config->readNumEntry( "MaxLogLen", 10000 ) ); + mWordWrapCB->setChecked( config->readBoolEntry("WordWrap", false ) ); + + config->setGroup( QString::null ); + enableButtonOK( false ); + enableButtonApply( false ); +} + +void KWatchGnuPGConfig::saveConfig() +{ + KConfig* config = kapp->config(); + config->setGroup("WatchGnuPG"); + config->writeEntry( "Executable", mExeED->url() ); + config->writeEntry( "Socket", mSocketED->url() ); + config->writeEntry( "LogLevel", log_levels[mLogLevelCB->currentItem()] ); + + config->setGroup("LogWindow"); + config->writeEntry( "MaxLogLen", mLoglenSB->value() ); + config->writeEntry( "WordWrap", mWordWrapCB->isChecked() ); + + config->setGroup( QString::null ); + config->sync(); + enableButtonOK( false ); + enableButtonApply( false ); +} + +void KWatchGnuPGConfig::slotChanged() +{ + enableButtonOK( true ); + enableButtonApply( true ); +} + +void KWatchGnuPGConfig::slotSave() +{ + saveConfig(); + emit reconfigure(); +} + +#include "kwatchgnupgconfig.moc" diff --git a/kwatchgnupg/aboutdata.cpp b/kwatchgnupg/kwatchgnupgconfig.h similarity index 52% copy from kwatchgnupg/aboutdata.cpp copy to kwatchgnupg/kwatchgnupgconfig.h index 68c918e9d..4a93b463b 100644 --- a/kwatchgnupg/aboutdata.cpp +++ b/kwatchgnupg/kwatchgnupgconfig.h @@ -1,73 +1,68 @@ /* - aboutdata.cpp + kwatchgnupgconfig.h This file is part of Kleopatra, the KDE keymanager - Copyright (c) 2004 Klar�vdalens Datakonsult AB + Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB Kleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Kleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#include "aboutdata.h" +#ifndef KWATCHGNUPGCONFIG_H +#define KWATCHGNUPGCONFIG_H -#include +#include -static const char kwatchgnupg_version[] = "1.0"; -static const char description[] = I18N_NOOP("GnuPG log viewer"); +class QCheckBox; +class QComboBox; +class QSpinBox; +class KURLRequester; -struct about_data { - const char * name; - const char * desc; - const char * email; - const char * web; -}; +class KWatchGnuPGConfig : public KDialogBase { + Q_OBJECT +public: + KWatchGnuPGConfig( QWidget* parent, const char* name = 0 ); -static const about_data authors[] = { - { "Steffen Hansen", I18N_NOOP("Original Author"), "hansen@kde.org", 0 }, -}; + void loadConfig(); + void saveConfig(); + +signals: + void reconfigure(); -#if 0 -// can't create zero size array - doesn't compile -static const about_data credits[] = { - // PENDING(steffen) add stuff +private slots: + void slotChanged(); + void slotSave(); + void slotSetHistorySizeUnlimited(); + +private: + KURLRequester* mExeED; + KURLRequester* mSocketED; + QComboBox* mLogLevelCB; + QSpinBox* mLoglenSB; + QCheckBox* mWordWrapCB; }; -#endif -AboutData::AboutData() - : KAboutData( "kwatchgnupg", I18N_NOOP("KWatchGnuPG"), - kwatchgnupg_version, description, License_GPL, - "(c) 2004 Klar\xC3\xA4lvdalens Datakonsult AB\n" ) -{ - using ::authors; - //using ::credits; - for ( unsigned int i = 0 ; i < sizeof authors / sizeof *authors ; ++i ) - addAuthor( authors[i].name, authors[i].desc, - authors[i].email, authors[i].web ); -#if 0 - for ( unsigned int i = 0 ; i < sizeof credits / sizeof *credits ; ++i ) - addCredit( credits[i].name, credits[i].desc, - credits[i].email, credits[i].web ); -#endif -} +#endif /* KWATCHGNUPGCONFIG_H */ + diff --git a/kwatchgnupg/kwatchgnupgmainwin.cpp b/kwatchgnupg/kwatchgnupgmainwin.cpp new file mode 100644 index 000000000..41e62160f --- /dev/null +++ b/kwatchgnupg/kwatchgnupgmainwin.cpp @@ -0,0 +1,292 @@ +/* + kwatchgnupgmainwin.cpp + + This file is part of Kleopatra, the KDE keymanager + Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB + + Kleopatra is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + Kleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#include "kwatchgnupgmainwin.h" +#include "kwatchgnupgconfig.h" +#include "tray.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define WATCHGNUPGBINARY "watchgnupg" +#define WATCHGNUPGSOCKET ( QDir::home().canonicalPath() + "/.gnupg/log-socket") + +KWatchGnuPGMainWindow::KWatchGnuPGMainWindow( QWidget* parent, const char* name ) + : KMainWindow( parent, name, WType_TopLevel ), mConfig(0) +{ + createActions(); + createGUI(); + + mCentralWidget = new QTextEdit( this, "central log view" ); + mCentralWidget->setTextFormat( QTextEdit::LogText ); + setCentralWidget( mCentralWidget ); + + mWatcher = new KProcIO( QTextCodec::codecForMib( 106 /*utf-8*/ ) ); + connect( mWatcher, SIGNAL( processExited(KProcess*) ), + this, SLOT( slotWatcherExited() ) ); + connect( mWatcher, SIGNAL( readReady(KProcIO*) ), + this, SLOT( slotReadStdout() ) ); + + slotReadConfig(); + mSysTray = new KWatchGnuPGTray( this ); + mSysTray->show(); + connect( mSysTray, SIGNAL( quitSelected() ), + this, SLOT( slotQuit() ) ); + setAutoSaveSettings(); +} + +KWatchGnuPGMainWindow::~KWatchGnuPGMainWindow() +{ + delete mWatcher; +} + +void KWatchGnuPGMainWindow::slotClear() +{ + mCentralWidget->clear(); + mCentralWidget->append( tr("[%1] Log cleared").arg( QDateTime::currentDateTime().toString(Qt::ISODate) ) ); +} + +void KWatchGnuPGMainWindow::createActions() +{ + (void)new KAction( i18n("C&lear History"), "history_clear", CTRL+Key_L, + this, SLOT( slotClear() ), + actionCollection(), "clear_log" ); + (void)KStdAction::saveAs( this, SLOT(slotSaveAs()), actionCollection() ); + (void)KStdAction::close( this, SLOT(close()), actionCollection() ); + (void)KStdAction::quit( this, SLOT(slotQuit()), actionCollection() ); + (void)KStdAction::preferences( this, SLOT(slotConfigure()), actionCollection() ); + ( void )KStdAction::keyBindings(this, SLOT(configureShortcuts()), actionCollection()); + ( void )KStdAction::configureToolbars(this, SLOT(slotConfigureToolbars()), actionCollection()); + +#if 0 + (void)new KAction( i18n("Configure KWatchGnuPG..."), QString::fromLatin1("configure"), + 0, this, SLOT( slotConfigure() ), + actionCollection(), "configure" ); +#endif + +} + +void KWatchGnuPGMainWindow::configureShortcuts() +{ + KKeyDialog::configure( actionCollection(), this ); +} + +void KWatchGnuPGMainWindow::slotConfigureToolbars() +{ + KEditToolbar dlg( factory() ); + + dlg.exec(); +} + +void KWatchGnuPGMainWindow::startWatcher() +{ + disconnect( mWatcher, SIGNAL( processExited(KProcess*) ), + this, SLOT( slotWatcherExited() ) ); + if( mWatcher->isRunning() ) { + mWatcher->kill(); + while( mWatcher->isRunning() ) { + kapp->eventLoop()->processEvents(QEventLoop::ExcludeUserInput); + } + mCentralWidget->append(tr("[%1] Log stopped") + .arg( QDateTime::currentDateTime().toString(Qt::ISODate))); + } + mWatcher->clearArguments(); + KConfig* config = kapp->config(); + config->setGroup("WatchGnuPG"); + *mWatcher << config->readEntry("Executable", WATCHGNUPGBINARY); + *mWatcher << "--force"; + *mWatcher << config->readEntry("Socket", WATCHGNUPGSOCKET); + config->setGroup(QString::null); + if( !mWatcher->start() ) { + KMessageBox::sorry( this, i18n("The watchgnupg logging process could not be started.\nPlease install watchgnupg somewhere in your $PATH.\nThis log window is now completely useless." ) ); + } else { + mCentralWidget->append( tr("[%1] Log started") + .arg( QDateTime::currentDateTime().toString(Qt::ISODate) ) ); + } + connect( mWatcher, SIGNAL( processExited(KProcess*) ), + this, SLOT( slotWatcherExited() ) ); +} + +void KWatchGnuPGMainWindow::setGnuPGConfig() +{ + QStringList logclients; + // Get config object + Kleo::CryptoConfig* cconfig = Kleo::CryptoBackendFactory::instance()->config(); + if ( !cconfig ) + return; + //Q_ASSERT( cconfig ); + KConfig* config = kapp->config(); + config->setGroup("WatchGnuPG"); + QStringList comps = cconfig->componentList(); + for( QStringList::const_iterator it = comps.begin(); it != comps.end(); ++it ) { + Kleo::CryptoConfigComponent* comp = cconfig->component( *it ); + Q_ASSERT(comp); + // Look for log-file entry in Debug group + Kleo::CryptoConfigGroup* group = comp->group("Debug"); + if( group ) { + Kleo::CryptoConfigEntry* entry = group->entry("log-file"); + if( entry ) { + entry->setStringValue( QString("socket://")+ + config->readEntry("Socket", + WATCHGNUPGSOCKET )); + logclients << QString("%1 (%2)").arg(*it).arg(comp->description()); + } + entry = group->entry("debug-level"); + if( entry ) { + entry->setStringValue( config->readEntry("LogLevel", "basic") ); + } + } + } + cconfig->sync(true); + if( logclients.isEmpty() ) { + KMessageBox::sorry( 0, i18n("There are no components available that support logging." ) ); + } +} + +void KWatchGnuPGMainWindow::slotWatcherExited() +{ + if( KMessageBox::questionYesNo( this, i18n("The watchgnupg logging process died.\nDo you want to try to restart it?") ) == KMessageBox::Yes ) { + mCentralWidget->append( i18n("====== Restarting logging process =====") ); + startWatcher(); + } else { + KMessageBox::sorry( this, i18n("The watchgnupg logging process is not running.\nThis log window is now completely useless." ) ); + } +} + +void KWatchGnuPGMainWindow::slotReadStdout() +{ + if ( !mWatcher ) + return; + QString str; + while( mWatcher->readln(str,false) > 0 ) { + mCentralWidget->append( str ); + if( !isVisible() ) { + // Change tray icon to show something happened + // PENDING(steffen) + mSysTray->setAttention(true); + } + } + QTimer::singleShot( 0, this, SLOT(slotAckRead()) ); +} + +void KWatchGnuPGMainWindow::slotAckRead() { + if ( mWatcher ) + mWatcher->ackRead(); +} + +void KWatchGnuPGMainWindow::show() +{ + mSysTray->setAttention(false); + KMainWindow::show(); +} + +void KWatchGnuPGMainWindow::slotSaveAs() +{ + QString filename = KFileDialog::getSaveFileName( QString::null, QString::null, + this, i18n("Save Log to File") ); + if( filename.isEmpty() ) return; + QFile file(filename); + if( file.exists() ) { + if( KMessageBox::Yes != + KMessageBox::warningYesNo( this, i18n("The file named \"%1\" already " + "exists. Are you sure you want " + "to overwrite it?").arg(filename), + i18n("Overwrite File") ) ) { + return; + } + } + if( file.open( IO_WriteOnly ) ) { + QTextStream st(&file); + st << mCentralWidget->text(); + file.close(); + } +} + +void KWatchGnuPGMainWindow::slotQuit() +{ + disconnect( mWatcher, SIGNAL( processExited(KProcess*) ), + this, SLOT( slotWatcherExited() ) ); + mWatcher->kill(); + kapp->quit(); +} + +void KWatchGnuPGMainWindow::slotConfigure() +{ + if( !mConfig ) { + mConfig = new KWatchGnuPGConfig( this, "config dialog" ); + connect( mConfig, SIGNAL( reconfigure() ), + this, SLOT( slotReadConfig() ) ); + } + mConfig->loadConfig(); + mConfig->exec(); +} + +void KWatchGnuPGMainWindow::slotReadConfig() +{ + KConfig* config = kapp->config(); + config->setGroup("LogWindow"); + mCentralWidget->setWordWrap( config->readBoolEntry("WordWrap", false) + ?QTextEdit::WidgetWidth + :QTextEdit::NoWrap ); + mCentralWidget->setMaxLogLines( config->readNumEntry( "MaxLogLen", 10000 ) ); + setGnuPGConfig(); + startWatcher(); +} + +bool KWatchGnuPGMainWindow::queryClose() +{ + if ( !kapp->sessionSaving() ) { + hide(); + return false; + } + return KMainWindow::queryClose(); +} + +#include "kwatchgnupgmainwin.moc" diff --git a/kwatchgnupg/aboutdata.cpp b/kwatchgnupg/kwatchgnupgmainwin.h similarity index 52% copy from kwatchgnupg/aboutdata.cpp copy to kwatchgnupg/kwatchgnupgmainwin.h index 68c918e9d..2021a6579 100644 --- a/kwatchgnupg/aboutdata.cpp +++ b/kwatchgnupg/kwatchgnupgmainwin.h @@ -1,73 +1,78 @@ /* - aboutdata.cpp + main.cpp This file is part of Kleopatra, the KDE keymanager - Copyright (c) 2004 Klar�vdalens Datakonsult AB + Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB Kleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Kleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#include "aboutdata.h" +#ifndef KWATCHGNUPGMAINWIN_H +#define KWATCHGNUPGMAINWIN_H -#include +#include -static const char kwatchgnupg_version[] = "1.0"; -static const char description[] = I18N_NOOP("GnuPG log viewer"); +class KWatchGnuPGTray; +class KWatchGnuPGConfig; +class KProcIO; +class QTextEdit; -struct about_data { - const char * name; - const char * desc; - const char * email; - const char * web; -}; +class KWatchGnuPGMainWindow : public KMainWindow { + Q_OBJECT +public: + KWatchGnuPGMainWindow( QWidget* parent = 0, const char* name = 0 ); + virtual ~KWatchGnuPGMainWindow(); +public slots: + void slotWatcherExited(); + void slotReadStdout(); + void slotAckRead(); -static const about_data authors[] = { - { "Steffen Hansen", I18N_NOOP("Original Author"), "hansen@kde.org", 0 }, -}; + void slotSaveAs(); + void slotQuit(); + void slotClear(); + + void slotConfigure(); + void slotConfigureToolbars(); + void configureShortcuts(); + void slotReadConfig(); + + virtual void show(); +protected: + virtual bool queryClose(); +private: + void createActions(); + void startWatcher(); + void setGnuPGConfig(); -#if 0 -// can't create zero size array - doesn't compile -static const about_data credits[] = { - // PENDING(steffen) add stuff + KProcIO* mWatcher; + + QTextEdit* mCentralWidget; + KWatchGnuPGTray* mSysTray; + KWatchGnuPGConfig* mConfig; }; -#endif - -AboutData::AboutData() - : KAboutData( "kwatchgnupg", I18N_NOOP("KWatchGnuPG"), - kwatchgnupg_version, description, License_GPL, - "(c) 2004 Klar\xC3\xA4lvdalens Datakonsult AB\n" ) -{ - using ::authors; - //using ::credits; - for ( unsigned int i = 0 ; i < sizeof authors / sizeof *authors ; ++i ) - addAuthor( authors[i].name, authors[i].desc, - authors[i].email, authors[i].web ); -#if 0 - for ( unsigned int i = 0 ; i < sizeof credits / sizeof *credits ; ++i ) - addCredit( credits[i].name, credits[i].desc, - credits[i].email, credits[i].web ); -#endif -} + +#endif /* KWATCHGNUPGMAINWIN_H */ + diff --git a/kwatchgnupg/main.cpp b/kwatchgnupg/main.cpp new file mode 100644 index 000000000..7c25a8da0 --- /dev/null +++ b/kwatchgnupg/main.cpp @@ -0,0 +1,96 @@ +/* + main.cpp + + This file is part of Kleopatra, the KDE keymanager + Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB + + Kleopatra is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + Kleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "aboutdata.h" +#include "kwatchgnupgmainwin.h" + +#include +#include +#include +#include +#include +#include +#include + +class KWatchGnuPGApplication : public KUniqueApplication { +public: + KWatchGnuPGApplication(); + ~KWatchGnuPGApplication(); + virtual int newInstance(); +private: + KWatchGnuPGMainWindow* mMainWin; +}; + +KWatchGnuPGApplication::KWatchGnuPGApplication() + : KUniqueApplication(), mMainWin(0) +{ +} + +KWatchGnuPGApplication::~KWatchGnuPGApplication() +{ + delete mMainWin; +} + +int KWatchGnuPGApplication::newInstance() +{ + if( !mMainWin ) { + mMainWin = new KWatchGnuPGMainWindow( 0, "kwatchgnupg mainwin" ); + setMainWidget( mMainWin ); + } + mMainWin->show(); + return KUniqueApplication::newInstance(); +} + +int main( int argc, char** argv ) +{ + AboutData aboutData; + + KCmdLineArgs::init(argc, argv, &aboutData); + static const KCmdLineOptions options[] = { + KCmdLineLastOption// End of options. + }; + KCmdLineArgs::addCmdLineOptions( options ); + KWatchGnuPGApplication::addCmdLineOptions(); + +#if 0 + if (!KWatchGnuPGApplication::start()) { + kdError() << "KWatchGnuPG is already running!" << endl; + return 0; + } +#endif + KWatchGnuPGApplication app; + return app.exec(); +} diff --git a/kwatchgnupg/aboutdata.cpp b/kwatchgnupg/tray.cpp similarity index 52% copy from kwatchgnupg/aboutdata.cpp copy to kwatchgnupg/tray.cpp index 68c918e9d..62024b14a 100644 --- a/kwatchgnupg/aboutdata.cpp +++ b/kwatchgnupg/tray.cpp @@ -1,73 +1,66 @@ /* - aboutdata.cpp + main.cpp This file is part of Kleopatra, the KDE keymanager - Copyright (c) 2004 Klar�vdalens Datakonsult AB + Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB Kleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Kleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#include "aboutdata.h" +#include "tray.h" +#include "kwatchgnupgmainwin.h" +#include #include +#include +#include +#include -static const char kwatchgnupg_version[] = "1.0"; -static const char description[] = I18N_NOOP("GnuPG log viewer"); +KWatchGnuPGTray::KWatchGnuPGTray( KWatchGnuPGMainWindow* mainwin ) + : KSystemTray( mainwin, "KWatchGnuPG Tray Window" ) +{ + kdDebug() << "KWatchGnuPGTray::KWatchGnuPGTray" << endl; -struct about_data { - const char * name; - const char * desc; - const char * email; - const char * web; -}; + KGlobal::iconLoader()->addAppDir( "kwatchgnupg" ); + + mNormalPix = loadIcon("kwatchgnupg"); + mAttentionPix = loadIcon("kwatchgnupg2"); -static const about_data authors[] = { - { "Steffen Hansen", I18N_NOOP("Original Author"), "hansen@kde.org", 0 }, -}; + setPixmap( mNormalPix ); + QToolTip::add( this, i18n("KWatchGnuPG Log Viewer") ); +} -#if 0 -// can't create zero size array - doesn't compile -static const about_data credits[] = { - // PENDING(steffen) add stuff -}; -#endif +KWatchGnuPGTray::~KWatchGnuPGTray() +{ +} -AboutData::AboutData() - : KAboutData( "kwatchgnupg", I18N_NOOP("KWatchGnuPG"), - kwatchgnupg_version, description, License_GPL, - "(c) 2004 Klar\xC3\xA4lvdalens Datakonsult AB\n" ) +void KWatchGnuPGTray::setAttention( bool att ) { - using ::authors; - //using ::credits; - for ( unsigned int i = 0 ; i < sizeof authors / sizeof *authors ; ++i ) - addAuthor( authors[i].name, authors[i].desc, - authors[i].email, authors[i].web ); -#if 0 - for ( unsigned int i = 0 ; i < sizeof credits / sizeof *credits ; ++i ) - addCredit( credits[i].name, credits[i].desc, - credits[i].email, credits[i].web ); -#endif + if( att ) setPixmap( mAttentionPix ); + else setPixmap( mNormalPix ); } + +#include "tray.moc" diff --git a/kwatchgnupg/aboutdata.cpp b/kwatchgnupg/tray.h similarity index 52% copy from kwatchgnupg/aboutdata.cpp copy to kwatchgnupg/tray.h index 68c918e9d..7f220ecad 100644 --- a/kwatchgnupg/aboutdata.cpp +++ b/kwatchgnupg/tray.h @@ -1,73 +1,55 @@ /* - aboutdata.cpp + main.cpp This file is part of Kleopatra, the KDE keymanager - Copyright (c) 2004 Klar�vdalens Datakonsult AB + Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB Kleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Kleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#include "aboutdata.h" +#ifndef TRAY_H +#define TRAY_H -#include +#include +#include -static const char kwatchgnupg_version[] = "1.0"; -static const char description[] = I18N_NOOP("GnuPG log viewer"); +class KWatchGnuPGMainWindow; -struct about_data { - const char * name; - const char * desc; - const char * email; - const char * web; -}; +class KWatchGnuPGTray : public KSystemTray { + Q_OBJECT +public: + KWatchGnuPGTray( KWatchGnuPGMainWindow* mainwin ); + virtual ~KWatchGnuPGTray(); -static const about_data authors[] = { - { "Steffen Hansen", I18N_NOOP("Original Author"), "hansen@kde.org", 0 }, +public slots: + void setAttention( bool att ); +private: + QPixmap mNormalPix; + QPixmap mAttentionPix; }; -#if 0 -// can't create zero size array - doesn't compile -static const about_data credits[] = { - // PENDING(steffen) add stuff -}; -#endif +#endif /* TRAY_H */ -AboutData::AboutData() - : KAboutData( "kwatchgnupg", I18N_NOOP("KWatchGnuPG"), - kwatchgnupg_version, description, License_GPL, - "(c) 2004 Klar\xC3\xA4lvdalens Datakonsult AB\n" ) -{ - using ::authors; - //using ::credits; - for ( unsigned int i = 0 ; i < sizeof authors / sizeof *authors ; ++i ) - addAuthor( authors[i].name, authors[i].desc, - authors[i].email, authors[i].web ); -#if 0 - for ( unsigned int i = 0 ; i < sizeof credits / sizeof *credits ; ++i ) - addCredit( credits[i].name, credits[i].desc, - credits[i].email, credits[i].web ); -#endif -} diff --git a/lib/backends/chiasmus/chiasmusbackend.cpp b/lib/backends/chiasmus/chiasmusbackend.cpp index f16dd60c0..64080e654 100644 --- a/lib/backends/chiasmus/chiasmusbackend.cpp +++ b/lib/backends/chiasmus/chiasmusbackend.cpp @@ -1,479 +1,479 @@ /* chiasmusbackend.cpp This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2005 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifdef HAVE_CONFIG_H #include #endif #include "chiasmusbackend.h" #include "config_data.h" #include "obtainkeysjob.h" #include "chiasmusjob.h" #include "kleo/cryptoconfig.h" #include #include #include #include #include #include #include #include #include #include namespace { // // The usual QVariant template helpers: // // to<> is a demarshaller. It's a class b/c you can't partially // specialise function templates yet. However, to<> can be used as if // it was a function: QString s = to( myVariant ); template class to {}; #define MAKE_TO( type, func ) \ template <> \ class to< type > { \ type m; \ public: \ to( const QVariant & v ) : m( v.func() ) {} \ operator type() const { return m; } \ } MAKE_TO( int, toInt ); MAKE_TO( unsigned int, toUInt ); template <> class to { KURL m; public: to( const QVariant & v ) { m.setPath( v.toString() ); } operator KURL() const { return m; } }; template class to< QValueList > { QValueList m; public: to( const QVariant & v ) { const QValueList vl = v.toList(); for ( QValueList::const_iterator it = vl.begin(), end = vl.end() ; it != end ; ++it ) m.push_back( to( *it ) ); } operator QValueList () const { return m; } }; template <> class to { KURL::List m; public: to( const QVariant & v ) { // wow, KURL::List is broken... it lacks conversion from and to QVL... m += to< QValueList >( v ); } operator KURL::List() const { return m; } }; // from<> is the demarshaller. See to<> for why this is a class... template struct from_helper : public QVariant { from_helper( const T & t ) : QVariant( t ) {} }; template QVariant from( const T & t ) { return from_helper( t ); } // some special types: template <> struct from_helper : public QVariant { from_helper( bool b ) : QVariant( b, int() ) {} }; template <> struct from_helper : public QVariant { from_helper( const KURL & url ) : QVariant( url.path() ) {} }; template struct from_helper< QValueList > : public QVariant { from_helper( const QValueList & l ) { QValueList result; for ( typename QValueList::const_iterator it = l.begin(), end = l.end() ; it != end ; ++it ) result.push_back( from( *it ) ); QVariant::operator=( result ); } }; template <> struct from_helper : public from_helper< QValueList > { from_helper( const KURL::List & l ) : from_helper< QValueList >( l ) {} }; class ChiasmusConfigEntry : public Kleo::CryptoConfigEntry { unsigned int mIdx; QVariant mValue; bool mDirty; public: ChiasmusConfigEntry( unsigned int i ) : Kleo::CryptoConfigEntry(), mIdx( i ), mValue( defaultValue() ), mDirty( false ) { assert( i < kleo_chiasmus_config_entries_dim ); } QString name() const { return kleo_chiasmus_config_entries[mIdx].name; } QString description() const { return i18n( kleo_chiasmus_config_entries[mIdx].description ); } bool isOptional() const { return kleo_chiasmus_config_entries[mIdx].is_optional; } bool isList() const { return kleo_chiasmus_config_entries[mIdx].is_list; } bool isRuntime() const { return kleo_chiasmus_config_entries[mIdx].is_runtime; } Level level() const { return static_cast( kleo_chiasmus_config_entries[mIdx].level ); } ArgType argType() const { return static_cast( kleo_chiasmus_config_entries[mIdx].type ); } bool isSet() const { return mValue != defaultValue(); } bool boolValue() const { return mValue.toBool(); } QString stringValue() const { return mValue.toString(); } int intValue() const { return mValue.toInt(); } unsigned int uintValue() const { return mValue.toUInt(); } KURL urlValue() const { if ( argType() != ArgType_Path && argType() != ArgType_DirPath ) return KURL( mValue.toString() ); KURL u; u.setPath( mValue.toString() ); return u; } unsigned int numberOfTimesSet() const { return 0; } QStringList stringValueList() const { return mValue.toStringList(); } QValueList intValueList() const { return to< QValueList >( mValue ); } QValueList uintValueList() const { return to< QValueList >( mValue ); } KURL::List urlValueList() const { if ( argType() != ArgType_Path && argType()!= ArgType_DirPath ) return mValue.toStringList(); else return to( mValue ); } void resetToDefault() { mValue = defaultValue(); mDirty = false; } void setBoolValue( bool value ) { setValue( QVariant( value, int() ) ); } void setStringValue( const QString & value ) { setValue( value ); } void setIntValue( int value ) { setValue( value ); } void setUIntValue( unsigned int value ) { setValue( value ); } void setURLValue( const KURL & value ) { if ( argType() != ArgType_Path && argType()!= ArgType_DirPath ) setValue( value.url() ); else setValue( value.path() ); } void setNumberOfTimesSet( unsigned int ) {} void setStringValueList( const QStringList & value ) { setValue( value ); } void setIntValueList( const QValueList & l ) { setValue( from( l ) ); } void setUIntValueList( const QValueList & l ) { setValue( from( l ) ); } void setURLValueList( const KURL::List & l ) { setValue( from( l ) ); } bool isDirty() const { return mDirty; } QVariant value() const { return mValue; } void sync( KConfigBase * config ) { if ( !mDirty ) return; mDirty = false; config->writeEntry( kleo_chiasmus_config_entries[mIdx].name, mValue ); } void read( const KConfigBase * config ) { mDirty = false; mValue = config->readPropertyEntry( kleo_chiasmus_config_entries[mIdx].name, defaultValue() ); } private: QVariant defaultValue() const; void setValue( const QVariant & value ) { mValue = value; mDirty = true; } }; QVariant ChiasmusConfigEntry::defaultValue() const { const kleo_chiasmus_config_data & data = kleo_chiasmus_config_entries[mIdx]; switch ( data.type ) { default: return QVariant(); case ArgType_None: if ( isList() ) return QValueList() << QVariant( data.defaults.boolean.value, int() ); else return QVariant( data.defaults.boolean.value, int() ); case ArgType_String: if ( isList() ) return QStringList( QString::fromLatin1( data.defaults.string ) ); else return QString::fromLatin1( data.defaults.string ); case ArgType_Int: if ( isList() ) return QValueList() << data.defaults.integer; else return data.defaults.integer; case ArgType_UInt: if ( isList() ) return QValueList() << data.defaults.unsigned_integer; else return data.defaults.unsigned_integer; case ArgType_Path: case ArgType_DirPath: if ( isList() ) return QValueList() << QString::fromLatin1( data.defaults.path ); else return QString::fromLatin1( data.defaults.path ); case ArgType_URL: case ArgType_LDAPURL: if ( isList() ) return QValueList() << QString::fromLatin1( data.defaults.url ); else return QString::fromLatin1( data.defaults.url ); } } class ChiasmusGeneralGroup : public Kleo::CryptoConfigGroup { mutable std::map mCache; mutable KConfig * mConfigObject; public: ChiasmusGeneralGroup() : Kleo::CryptoConfigGroup(), mConfigObject( 0 ) {} ~ChiasmusGeneralGroup() { clear(); delete mConfigObject; } QString name() const { return "General"; } QString iconName() const { return "chiasmus_chi"; } QString description() const { return i18n( "General" ); } Kleo::CryptoConfigEntry::Level level() const { return Kleo::CryptoConfigEntry::Level_Basic; } QStringList entryList() const { QStringList result; for ( unsigned int i = 0 ; i < kleo_chiasmus_config_entries_dim ; ++i ) result.push_back( kleo_chiasmus_config_entries[i].name ); return result; } Kleo::CryptoConfigEntry * entry( const QString & name ) const { if ( ChiasmusConfigEntry * entry = mCache[name] ) return entry; const KConfigGroup group( configObject(), "Chiasmus" ); for ( unsigned int i = 0 ; i < kleo_chiasmus_config_entries_dim ; ++i ) if ( name == kleo_chiasmus_config_entries[i].name ) { ChiasmusConfigEntry * entry = new ChiasmusConfigEntry( i ); entry->read( &group ); return mCache[name] = entry; } return 0; } void sync() { KConfigGroup group( configObject(), "Chiasmus" ); for ( std::map::const_iterator it = mCache.begin(), end = mCache.end() ; it != end ; ++it ) it->second->sync( &group ); group.sync(); clear(); } private: KConfig * configObject() const { if ( !mConfigObject ) // this is unsafe. We're a lib, used by concurrent apps. mConfigObject = new KConfig( "chiasmusbackendrc" ); return mConfigObject; } void clear() { for ( std::map::const_iterator it = mCache.begin(), end = mCache.end() ; it != end ; ++it ) delete it->second; mCache.clear(); } }; class ChiasmusComponent : public Kleo::CryptoConfigComponent { mutable ChiasmusGeneralGroup * mGeneralGroup; public: ChiasmusComponent() : Kleo::CryptoConfigComponent(), mGeneralGroup( 0 ) {} ~ChiasmusComponent() { delete mGeneralGroup; } void sync() { if ( mGeneralGroup ) mGeneralGroup->sync(); } QString name() const { return "Chiasmus"; } QString iconName() const { return "chiasmus_chi"; } QString description() const { return i18n( "Chiasmus" ); } QStringList groupList() const { return QStringList() << "General"; } Kleo::CryptoConfigGroup * group( const QString & name ) const { if ( name != "General" ) return 0; if ( !mGeneralGroup ) mGeneralGroup = new ChiasmusGeneralGroup(); return mGeneralGroup; } }; } class Kleo::ChiasmusBackend::CryptoConfig : public Kleo::CryptoConfig { mutable ChiasmusComponent * mComponent; public: CryptoConfig() : Kleo::CryptoConfig(), mComponent( 0 ) {} ~CryptoConfig() { delete mComponent; } QStringList componentList() const { return QStringList() << "Chiasmus" ; } ChiasmusComponent * component( const QString & name ) const { if ( name != "Chiasmus" ) return 0; if ( !mComponent ) mComponent = new ChiasmusComponent(); return mComponent; } void sync( bool ) { if ( mComponent ) mComponent->sync(); } void clear() { delete mComponent; mComponent = 0; } }; class Kleo::ChiasmusBackend::Protocol : public Kleo::CryptoBackend::Protocol { Kleo::CryptoConfig * mCryptoConfig; public: Protocol( Kleo::CryptoConfig * config ) : Kleo::CryptoBackend::Protocol(), mCryptoConfig( config ) { assert( config ); } ~Protocol() {} QString name() const { return "Chiasmus"; } QString displayName() const { return i18n( "Chiasmus command line tool" ); } KeyListJob * keyListJob( bool, bool, bool ) const { return 0; } EncryptJob * encryptJob( bool, bool ) const { return 0; } DecryptJob * decryptJob() const { return 0; } SignJob * signJob( bool, bool ) const { return 0; } VerifyDetachedJob * verifyDetachedJob( bool ) const { return 0; } VerifyOpaqueJob * verifyOpaqueJob( bool ) const { return 0; } KeyGenerationJob * keyGenerationJob() const { return 0; } ImportJob * importJob() const { return 0; } ExportJob * publicKeyExportJob( bool ) const { return 0; } ExportJob * secretKeyExportJob( bool ) const { return 0; } DownloadJob * downloadJob( bool ) const { return 0; } DeleteJob * deleteJob() const { return 0; } SignEncryptJob * signEncryptJob( bool, bool ) const { return 0; } DecryptVerifyJob * decryptVerifyJob( bool ) const { return 0; } RefreshKeysJob * refreshKeysJob() const { return 0; } SpecialJob * specialJob( const char * type, const QMap & args ) const { if ( qstricmp( type, "x-obtain-keys" ) == 0 && args.size() == 0 ) return new ObtainKeysJob(); if ( qstricmp( type, "x-encrypt" ) == 0 && args.size() == 0 ) return new ChiasmusJob( ChiasmusJob::Encrypt ); if ( qstricmp( type, "x-decrypt" ) == 0 && args.size() == 0 ) return new ChiasmusJob( ChiasmusJob::Decrypt ); kdDebug(5150) << "ChiasmusBackend::Protocol: tried to instantiate unknown job type \"" << type << "\"" << endl; return 0; } }; Kleo::ChiasmusBackend * Kleo::ChiasmusBackend::self = 0; Kleo::ChiasmusBackend::ChiasmusBackend() : Kleo::CryptoBackend(), mCryptoConfig( 0 ), mProtocol( 0 ) { self = this; } Kleo::ChiasmusBackend::~ChiasmusBackend() { self = 0; delete mCryptoConfig; delete mProtocol; } QString Kleo::ChiasmusBackend::name() const { return "Chiasmus"; } QString Kleo::ChiasmusBackend::displayName() const { return i18n( "Chiasmus" ); } Kleo::CryptoConfig * Kleo::ChiasmusBackend::config() const { if ( !mCryptoConfig ) mCryptoConfig = new CryptoConfig(); return mCryptoConfig; } Kleo::CryptoBackend::Protocol * Kleo::ChiasmusBackend::protocol( const char * name ) const { if ( qstricmp( name, "Chiasmus" ) != 0 ) return 0; if ( !mProtocol ) if ( checkForChiasmus() ) mProtocol = new Protocol( config() ); return mProtocol; } bool Kleo::ChiasmusBackend::checkForOpenPGP( QString * reason ) const { if ( reason ) *reason = i18n( "Unsupported protocol \"%1\"" ).arg( "OpenPGP" ); return false; } bool Kleo::ChiasmusBackend::checkForSMIME( QString * reason ) const { if ( reason ) *reason = i18n( "Unsupported protocol \"%1\"" ).arg( "SMIME" ); return false; } bool Kleo::ChiasmusBackend::checkForChiasmus( QString * reason ) const { // kills the protocol instance when we return false: std::auto_ptr tmp( mProtocol ); mProtocol = 0; const CryptoConfigEntry * path = config()->entry( "Chiasmus", "General", "path" ); assert( path ); assert( path->argType() == CryptoConfigEntry::ArgType_Path ); const QString chiasmus = path->urlValue().path(); const QFileInfo fi( KShell::tildeExpand( chiasmus ) ); if ( !fi.isExecutable() ) { if ( reason ) *reason = i18n( "File \"%1\" does not exist or is not executable." ).arg( chiasmus ); return false; } // FIXME: more checks? mProtocol = tmp.release(); return true; } bool Kleo::ChiasmusBackend::checkForProtocol( const char * name, QString * reason ) const { if ( qstricmp( name, "Chiasmus" ) == 0 ) return checkForChiasmus( reason ); if ( reason ) *reason = i18n( "Unsupported protocol \"%1\"" ).arg( name ); return 0; } bool Kleo::ChiasmusBackend::supportsProtocol( const char * name ) const { return qstricmp( name, "Chiasmus" ) == 0; } const char * Kleo::ChiasmusBackend::enumerateProtocols( int i ) const { return i == 0 ? "Chiasmus" : 0 ; } diff --git a/lib/backends/chiasmus/chiasmusbackend.h b/lib/backends/chiasmus/chiasmusbackend.h index bc584312a..6d51cad77 100644 --- a/lib/backends/chiasmus/chiasmusbackend.h +++ b/lib/backends/chiasmus/chiasmusbackend.h @@ -1,86 +1,86 @@ /* -*- mode: C++; c-file-style: "gnu" -*- chiasmusbackend.h This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2005 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifndef __KLEO_CHIASMUSBACKEND_H__ #define __KLEO_CHIASMUSBACKEND_H__ #include "kleo/cryptobackend.h" class CryptPlugWrapper; namespace Kleo { class CryptoConfig; } class QString; namespace Kleo { class ChiasmusBackend : public Kleo::CryptoBackend { public: ChiasmusBackend(); ~ChiasmusBackend(); static const ChiasmusBackend * instance() { return self; } QString name() const; QString displayName() const; Kleo::CryptoConfig * config() const; Kleo::CryptoBackend::Protocol * openpgp() const { return 0; } Kleo::CryptoBackend::Protocol * smime() const { return 0; } Kleo::CryptoBackend::Protocol * protocol( const char * name ) const; bool checkForOpenPGP( QString * reason=0 ) const; bool checkForSMIME( QString * reason=0 ) const; bool checkForChiasmus( QString * reason=0 ) const; bool checkForProtocol( const char * name, QString * reason=0 ) const; bool supportsOpenPGP() const { return false; } bool supportsSMIME() const { return false; } bool supportsProtocol( const char * name ) const; const char * enumerateProtocols( int i ) const; private: class CryptoConfig; class Protocol; mutable CryptoConfig * mCryptoConfig; mutable Protocol * mProtocol; static ChiasmusBackend * self; }; } #endif // __KLEO_CHIASMUSBACKEND_H__ diff --git a/lib/backends/chiasmus/chiasmusjob.cpp b/lib/backends/chiasmus/chiasmusjob.cpp index 5227fed3f..c62687c15 100644 --- a/lib/backends/chiasmus/chiasmusjob.cpp +++ b/lib/backends/chiasmus/chiasmusjob.cpp @@ -1,220 +1,220 @@ /* chiasmusjob.cpp This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2005 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifdef HAVE_CONFIG_H #include #endif #include "chiasmusjob.h" #include "chiasmusbackend.h" #include "symcryptrunprocessbase.h" #include "kleo/cryptoconfig.h" #include "ui/passphrasedialog.h" #include #include #include #include #include #include #include #include #include #include Kleo::ChiasmusJob::ChiasmusJob( Mode mode ) : Kleo::SpecialJob( 0, 0 ), mSymCryptRun( 0 ), mError( 0 ), mCanceled( false ), mTimeout( false ), mMode( mode ) { } Kleo::ChiasmusJob::~ChiasmusJob() {} GpgME::Error Kleo::ChiasmusJob::setup() { if ( !checkPreconditions() ) return mError = gpg_error( GPG_ERR_INV_VALUE ); const Kleo::CryptoConfigEntry * class_ = ChiasmusBackend::instance()->config()->entry( "Chiasmus", "General", "symcryptrun-class" ); const Kleo::CryptoConfigEntry * chiasmus = ChiasmusBackend::instance()->config()->entry( "Chiasmus", "General", "path" ); const Kleo::CryptoConfigEntry * timeoutEntry = ChiasmusBackend::instance()->config()->entry( "Chiasmus", "General", "timeout" ); if ( !class_ || !chiasmus || !timeoutEntry ) return mError = gpg_error( GPG_ERR_INTERNAL ); mSymCryptRun = new SymCryptRunProcessBase( class_->stringValue(), KShell::tildeExpand( chiasmus->urlValue().path() ), mKey, mOptions, mMode == Encrypt ? SymCryptRunProcessBase::Encrypt : SymCryptRunProcessBase::Decrypt, this, "symcryptrun" ); QTimer::singleShot( timeoutEntry->uintValue() * 1000, this, SLOT( slotTimeout() ) ); return 0; } namespace { struct LaterDeleter { QObject * _this; LaterDeleter( QObject * o ) : _this( o ) {} ~LaterDeleter() { if ( _this ) _this->deleteLater(); } void disable() { _this = 0; } }; } GpgME::Error Kleo::ChiasmusJob::start() { LaterDeleter d( this ); if ( const GpgME::Error err = setup() ) return mError = err; connect( mSymCryptRun, SIGNAL(processExited(KProcess*)), this, SLOT(slotProcessExited(KProcess*)) ); if ( !mSymCryptRun->launch( mInput ) ) return mError = gpg_error( GPG_ERR_ENOENT ); // what else? d.disable(); return mError = 0; } GpgME::Error Kleo::ChiasmusJob::slotProcessExited( KProcess * proc ) { if ( proc != mSymCryptRun ) mError = gpg_error( GPG_ERR_INTERNAL ); else if ( mCanceled ) mError = gpg_error( GPG_ERR_CANCELED ); else if ( mTimeout ) mError = gpg_error( GPG_ERR_TIMEOUT ); else if ( !proc->normalExit() ) mError = gpg_error( GPG_ERR_GENERAL ); else switch ( proc->exitStatus() ) { case 0: // success mOutput = mSymCryptRun->output(); mError = 0; break; default: case 1: // Some error occured mStderr = mSymCryptRun->stderr(); mError = gpg_error( GPG_ERR_GENERAL ); break; case 2: // No valid passphrase was provided mError = gpg_error( GPG_ERR_INV_PASSPHRASE ); break; case 3: // Canceled mError = gpg_error( GPG_ERR_CANCELED ); break; } const Kleo::CryptoConfigEntry * showOutput = ChiasmusBackend::instance()->config()->entry( "Chiasmus", "General", "show-output" ); if ( showOutput && showOutput->boolValue() ) { showChiasmusOutput(); } emit done(); emit SpecialJob::result( mError, QVariant( mOutput ) ); return mError; } void Kleo::ChiasmusJob::showChiasmusOutput() { kdDebug() << k_funcinfo << endl; if ( mStderr.isEmpty() ) return; KMessageBox::information( 0 /*how to get a parent widget?*/, mStderr, i18n( "Output from chiasmus" ) ); } GpgME::Error Kleo::ChiasmusJob::exec() { if ( const GpgME::Error err = setup() ) return mError = err; if ( !mSymCryptRun->launch( mInput, KProcess::Block ) ) { delete mSymCryptRun; mSymCryptRun = 0; return mError = gpg_error( GPG_ERR_ENOENT ); // what else? } const GpgME::Error err = slotProcessExited( mSymCryptRun ); delete mSymCryptRun; mSymCryptRun = 0; return err; } bool Kleo::ChiasmusJob::checkPreconditions() const { return !mKey.isEmpty(); } void Kleo::ChiasmusJob::slotCancel() { if ( mSymCryptRun ) mSymCryptRun->kill(); mCanceled = true; } void Kleo::ChiasmusJob::slotTimeout() { if ( !mSymCryptRun ) return; mSymCryptRun->kill(); mTimeout = true; } void Kleo::ChiasmusJob::showErrorDialog( QWidget * parent, const QString & caption ) const { if ( !mError ) return; if ( mError.isCanceled() ) return; const QString msg = ( mMode == Encrypt ? i18n( "Encryption failed: %1" ) : i18n( "Decryption failed: %1" ) ) .arg( QString::fromLocal8Bit( mError.asString() ) ); if ( !mStderr.isEmpty() ) { const QString details = i18n( "The following was received on stderr:\n%1" ).arg( mStderr ); KMessageBox::detailedError( parent, msg, details, caption ); } else { KMessageBox::error( parent, msg, caption ); } } #include "chiasmusjob.moc" diff --git a/lib/backends/chiasmus/chiasmusjob.h b/lib/backends/chiasmus/chiasmusjob.h index 20da6b6ac..6393a0905 100644 --- a/lib/backends/chiasmus/chiasmusjob.h +++ b/lib/backends/chiasmus/chiasmusjob.h @@ -1,116 +1,116 @@ /* -*- mode: C++; c-file-style: "gnu" -*- chiasmusjob.h This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2005 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifndef __KLEO_CHIASMUSJOB_H__ #define __KLEO_CHIASMUSJOB_H__ #include "kleo/specialjob.h" #include #include class KProcess; namespace Kleo { class SymCryptRunProcessBase; /** @short SpecialJob for Chiasmus operations */ class ChiasmusJob : public Kleo::SpecialJob { Q_OBJECT Q_ENUMS( Mode ) Q_PROPERTY( Mode mode READ mode ) Q_PROPERTY( QString key READ key WRITE setKey ) Q_PROPERTY( QString options READ options WRITE setOptions ) Q_PROPERTY( QByteArray input READ input WRITE setInput ) Q_PROPERTY( QByteArray result READ result ) public: enum Mode { Encrypt, Decrypt }; ChiasmusJob( Mode op ); ~ChiasmusJob(); /*!\reimp SpecialJob */ GpgME::Error start(); /*!\reimp SpecialJob */ GpgME::Error exec(); /*!\reimp Kleo::Job */ void showErrorDialog( QWidget *, const QString & ) const; Mode mode() const { return mMode; } QString key() const { return mKey; } void setKey( const QString & key ) { mKey = key; } QString options() const { return mOptions; } void setOptions( const QString & options ) { mOptions = options; } QByteArray input() const { return mInput; } void setInput( const QByteArray & input ) { mInput = input; } //using SpecialJob::result; QByteArray result() const { return mOutput; } public slots: void slotCancel(); private slots: GpgME::Error slotProcessExited( KProcess * ); void slotTimeout(); private: bool checkPreconditions() const; GpgME::Error setup(); void showChiasmusOutput(); private: SymCryptRunProcessBase * mSymCryptRun; QString mKey; QString mOptions; QByteArray mInput, mOutput; GpgME::Error mError; QString mStderr; bool mCanceled; bool mTimeout; const Mode mMode; }; } #endif // __KLEO_CHIASMUSJOB_H__ diff --git a/lib/backends/chiasmus/chiasmuslibrary.cpp b/lib/backends/chiasmus/chiasmuslibrary.cpp index 503496304..2e3225492 100644 --- a/lib/backends/chiasmus/chiasmuslibrary.cpp +++ b/lib/backends/chiasmus/chiasmuslibrary.cpp @@ -1,115 +1,115 @@ /* chiasmuslibrary.cpp This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2005 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #include "chiasmuslibrary.h" #include "chiasmusbackend.h" #include "kleo/cryptoconfig.h" #include #include #include #include #include #include #include #include #include Kleo::ChiasmusLibrary * Kleo::ChiasmusLibrary::self = 0; Kleo::ChiasmusLibrary::ChiasmusLibrary() : mXiaLibrary( 0 ) { self = this; } Kleo::ChiasmusLibrary::~ChiasmusLibrary() { //delete mXiaLibrary; // hmm, how to get rid of it, then? } Kleo::ChiasmusLibrary::main_func Kleo::ChiasmusLibrary::chiasmus( QString * reason ) const { assert( ChiasmusBackend::instance() ); assert( ChiasmusBackend::instance()->config() ); const CryptoConfigEntry * lib = ChiasmusBackend::instance()->config()->entry( "Chiasmus", "General", "lib" ); assert( lib ); const QString libfile = lib->urlValue().path(); if ( !mXiaLibrary ) mXiaLibrary = KLibLoader::self()->library( QFile::encodeName( libfile ) ); if ( !mXiaLibrary ) { if ( reason ) *reason = i18n( "Failed to load %1: %2" ) .arg( libfile,KLibLoader::self()->lastErrorMessage() ); kdDebug(5150) << "ChiasmusLibrary: loading \"" << libfile << "\" failed: " << KLibLoader::self()->lastErrorMessage() << endl; return 0; } if ( !mXiaLibrary->hasSymbol( "Chiasmus" ) ) { if ( reason ) *reason = i18n( "Failed to load %1: %2" ) .arg( libfile, i18n( "Library does not contain the symbol \"Chiasmus\"." ) ); kdDebug(5150) << "ChiasmusLibrary: loading \"" << libfile << "\" failed: " << "Library does not contain the symbol \"Chiasmus\"." << endl; return 0; } void * symbol = mXiaLibrary->symbol( "Chiasmus" ); assert( symbol ); return ( main_func )symbol; } namespace { class ArgvProvider { char ** mArgv; int mArgc; public: ArgvProvider( const QValueVector & args ) { mArgv = new char * [args.size()]; for ( unsigned int i = 0 ; i < args.size() ; ++i ) mArgv[i] = strdup( args[i].data() ); } ~ArgvProvider() { std::for_each( mArgv, mArgv + mArgc, std::free ); delete[] mArgv; } char ** argv() const { return mArgv; } }; } int Kleo::ChiasmusLibrary::perform( const QValueVector & args ) const { if ( main_func func = chiasmus() ) return func( args.size(), ArgvProvider( args ).argv() ); else return -1; } diff --git a/lib/backends/chiasmus/chiasmuslibrary.h b/lib/backends/chiasmus/chiasmuslibrary.h index 1759b4fc7..b04e162b4 100644 --- a/lib/backends/chiasmus/chiasmuslibrary.h +++ b/lib/backends/chiasmus/chiasmuslibrary.h @@ -1,68 +1,68 @@ /* -*- mode: C++; c-file-style: "gnu" -*- chiasmuslibrary.h This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2005 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifndef __KLEO_CHIASMUSLIBRARY_H__ #define __KLEO_CHIASMUSLIBRARY_H__ #include #include class KLibrary; namespace Kleo { /** @short small helper class to load xia.o through xia.so and make the functionality available. */ class ChiasmusLibrary { ChiasmusLibrary(); ~ChiasmusLibrary(); public: static const ChiasmusLibrary * instance(); static void deleteInstance(); int perform( const QValueVector & args ) const; private: typedef int ( *main_func )( int, char** ); main_func chiasmus( QString * reason=0 ) const; private: static ChiasmusLibrary * self; mutable KLibrary * mXiaLibrary; }; } #endif // __KLEO_CHIASMUSLIBRARY_H__ diff --git a/lib/backends/chiasmus/config_data.c b/lib/backends/chiasmus/config_data.c index ecbb04644..bb3f33916 100644 --- a/lib/backends/chiasmus/config_data.c +++ b/lib/backends/chiasmus/config_data.c @@ -1,95 +1,95 @@ /* chiasmusbackend.cpp This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2005 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifdef HAVE_CONFIG_H #include #endif #include "config_data.h" #include "kleo/cryptoconfig.h" /* for the enum values */ /* This data structure uses C99 designated initializers. This is why it's in a .c file, and not in a .cpp file. If your compiler doesn't like this, just don't compile Chiasmus support, or live without the wrapper option :) Sorry. */ #ifdef PATH # undef PATH #endif #ifdef HAVE_C99_INITIALIZERS # define PATH .path = #else # define PATH #endif #define I18N_NOOP(x) (x) const struct kleo_chiasmus_config_data kleo_chiasmus_config_entries[] = { { "path", I18N_NOOP( "Path to Chiasmus executable" ), Level_Basic, ArgType_Path, { PATH "/usr/local/bin/chiasmus" }, /* in the absence of C99, we assume path is first in the union here */ 0, 0, 1 }, { "keydir", I18N_NOOP( "Key directory" ), Level_Basic, ArgType_DirPath, { PATH "~/.chiasmus/keys" }, 0, 0, 1 /* FIXME: should be a list */ }, #ifdef HAVE_C99_INITIALIZERS { "show-output", I18N_NOOP( "Show output from chiasmus operations" ), Level_Expert, ArgType_None, { .boolean = { .value = 0, .numTimesSet = 0 } }, 0, 0, 1 }, { "symcryptrun-class", I18N_NOOP( "SymCryptRun class to use" ), Level_Expert, ArgType_String, { .string = "confucius" }, 0, 0, 1 }, { "timeout", I18N_NOOP( "Timeout in seconds for Chiasmus operations" ), Level_Advanced, ArgType_UInt, { .unsigned_integer = 60 }, 0, 0, 1 }, #endif /* HAVE_C99_INITIALIZERS */ }; const unsigned int kleo_chiasmus_config_entries_dim = sizeof kleo_chiasmus_config_entries / sizeof *kleo_chiasmus_config_entries ; diff --git a/lib/backends/chiasmus/obtainkeysjob.cpp b/lib/backends/chiasmus/obtainkeysjob.cpp index 4910c2d0d..a9de8d658 100644 --- a/lib/backends/chiasmus/obtainkeysjob.cpp +++ b/lib/backends/chiasmus/obtainkeysjob.cpp @@ -1,126 +1,126 @@ /* obtainkeysjob.cpp This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2005 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifdef HAVE_CONFIG_H #include #endif #include "obtainkeysjob.h" #include "chiasmusbackend.h" #include "kleo/cryptoconfig.h" #include #include #include #include #include #include #include #include #include #include Kleo::ObtainKeysJob::ObtainKeysJob() : SpecialJob( 0, 0 ), mIndex( 0 ), mCanceled( false ) { assert( ChiasmusBackend::instance() ); assert( ChiasmusBackend::instance()->config() ); const CryptoConfigEntry * keypaths = ChiasmusBackend::instance()->config()->entry( "Chiasmus", "General", "keydir" ); assert( keypaths ); mKeyPaths = QStringList( keypaths->urlValue().path() ); } Kleo::ObtainKeysJob::~ObtainKeysJob() {} GpgME::Error Kleo::ObtainKeysJob::start() { QTimer::singleShot( 0, this, SLOT(slotPerform()) ); return mError = 0; } GpgME::Error Kleo::ObtainKeysJob::exec() { slotPerform( false ); return mError; } void Kleo::ObtainKeysJob::slotCancel() { mCanceled = true; } void Kleo::ObtainKeysJob::slotPerform() { slotPerform( true ); } void Kleo::ObtainKeysJob::slotPerform( bool async ) { if ( mCanceled && !mError ) mError = gpg_error( GPG_ERR_CANCELED ); if ( mIndex >= mKeyPaths.size() || mError ) { emit done(); emit SpecialJob::result( mError, QVariant( mResult ) ); return; } emit progress( i18n( "Scanning directory %1..." ).arg( mKeyPaths[mIndex] ), mIndex, mKeyPaths.size() ); const QDir dir( KShell::tildeExpand( mKeyPaths[mIndex] ) ); if ( const QFileInfoList * xisFiles = dir.entryInfoList( "*.xis;*.XIS", QDir::Files ) ) for ( QFileInfoList::const_iterator it = xisFiles->begin(), end = xisFiles->end() ; it != end ; ++it ) if ( (*it)->isReadable() ) mResult.push_back( (*it)->absFilePath() ); ++mIndex; if ( async ) QTimer::singleShot( 0, this, SLOT(slotPerform()) ); else slotPerform( false ); } void Kleo::ObtainKeysJob::showErrorDialog( QWidget * parent, const QString & caption ) const { if ( !mError ) return; if ( mError.isCanceled() ) return; const QString msg = QString::fromUtf8( mError.asString() ); KMessageBox::error( parent, msg, caption ); } #include "obtainkeysjob.moc" diff --git a/lib/backends/chiasmus/obtainkeysjob.h b/lib/backends/chiasmus/obtainkeysjob.h index 5591e1629..4b8392d46 100644 --- a/lib/backends/chiasmus/obtainkeysjob.h +++ b/lib/backends/chiasmus/obtainkeysjob.h @@ -1,101 +1,101 @@ /* -*- mode: C++; c-file-style: "gnu" -*- obtainkeysjob.h This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2005 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifndef __KLEO_OBTAINKEYSJOB_H__ #define __KLEO_OBTAINKEYSJOB_H__ #include "kleo/specialjob.h" #include #include namespace Kleo { /** @short SpecialJob for listing Chiasmus key files. In the Chiasmus system, keys are mapped 1:1 to files. Furthermore, we have to definition of the format of those keys, so we cannot display more than the filename anyway. Due to all of these limitations, we don't use KeyListJob here, but roll our own interface. The name of the function is x-obtain-keys. It takes no parameters. To use, create an ObtainKeysJob instance like this: Kleo::SpecialJob * job = protocol->specialJob("x-obtain-keys", QMap()); The resulting QVariant will contain a QStringList containing the absolute filenames of the keys found in the configured key files. */ class ObtainKeysJob : public Kleo::SpecialJob { Q_OBJECT Q_PROPERTY( QStringList result READ result ) public: ObtainKeysJob(); ~ObtainKeysJob(); /*!\reimp SpecialJob */ GpgME::Error start(); /*!\reimp SpecialJob */ GpgME::Error exec(); /*!\reimp Kleo::Job */ void showErrorDialog( QWidget *, const QString & ) const; //using SpecialJob::result; QStringList result() const { return mResult; } public slots: void slotCancel(); private slots: void slotPerform(); void slotPerform( bool async ); private: GpgME::Error mError; QStringList mKeyPaths; unsigned int mIndex; QStringList mResult; bool mCanceled; }; } #endif // __KLEO_OBTAINKEYSJOB_H__ diff --git a/lib/backends/chiasmus/symcryptrunprocessbase.cpp b/lib/backends/chiasmus/symcryptrunprocessbase.cpp index 5426fe577..1b8627252 100644 --- a/lib/backends/chiasmus/symcryptrunprocessbase.cpp +++ b/lib/backends/chiasmus/symcryptrunprocessbase.cpp @@ -1,109 +1,109 @@ /* symcryptrunbackend.cpp This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2005 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #include "symcryptrunprocessbase.h" #include #include #include #include #include #include Kleo::SymCryptRunProcessBase::SymCryptRunProcessBase( const QString & class_, const QString & program, const QString & keyFile, const QString & options, Operation mode, QObject * parent, const char * name ) : KProcess( parent, name ), mOperation( mode ), mOptions( options ) { *this << "symcryptrun" << "--class" << class_ << "--program" << program << "--keyfile" << keyFile << ( mode == Encrypt ? "--encrypt" : "--decrypt" ); } Kleo::SymCryptRunProcessBase::~SymCryptRunProcessBase() {} bool Kleo::SymCryptRunProcessBase::launch( const QByteArray & input, RunMode rm ) { connect( this, SIGNAL(receivedStdout(KProcess*,char*,int)), this, SLOT(slotReceivedStdout(KProcess*,char*,int)) ); connect( this, SIGNAL(receivedStderr(KProcess*,char*,int)), this, SLOT(slotReceivedStderr(KProcess*,char*,int)) ); if ( rm == Block ) { KTempFile tempfile; tempfile.setAutoDelete( true ); if ( QFile * file = tempfile.file() ) file->writeBlock( input ); else return false; tempfile.close(); *this << "--input" << tempfile.name(); addOptions(); return KProcess::start( Block, All ); } else { addOptions(); const bool ok = KProcess::start( rm, All ); if ( !ok ) return ok; mInput = input.copy(); writeStdin( mInput.begin(), mInput.size() ); connect( this, SIGNAL(wroteStdin(KProcess*)), this, SLOT(closeStdin()) ); return true; } } void Kleo::SymCryptRunProcessBase::addOptions() { if ( !mOptions.isEmpty() ) { const QStringList args = KShell::splitArgs( mOptions ); *this << "--" << args; } } void Kleo::SymCryptRunProcessBase::slotReceivedStdout( KProcess * proc, char * buf, int len ) { Q_ASSERT( proc == this ); const int oldsize = mOutput.size(); mOutput.resize( oldsize + len ); memcpy( mOutput.data() + oldsize, buf, len ); } void Kleo::SymCryptRunProcessBase::slotReceivedStderr( KProcess * proc, char * buf, int len ) { Q_ASSERT( proc == this ); if ( len > 0 ) mStderr += QString::fromLocal8Bit( buf, len ); } #include "symcryptrunprocessbase.moc" diff --git a/lib/backends/chiasmus/symcryptrunprocessbase.h b/lib/backends/chiasmus/symcryptrunprocessbase.h index 8415c0f4b..3f499d283 100644 --- a/lib/backends/chiasmus/symcryptrunprocessbase.h +++ b/lib/backends/chiasmus/symcryptrunprocessbase.h @@ -1,81 +1,81 @@ /* symcryptrunbackend.h This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2005 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifndef __KLEO_BACKEND_CHIASMUS__SYMCRYPTRUNPROCESSBASE_H__ #define __KLEO_BACKEND_CHIASMUS__SYMCRYPTRUNPROCESSBASE_H__ #include #include class QString; namespace Kleo { class SymCryptRunProcessBase : public KProcess { Q_OBJECT public: enum Operation { Encrypt, Decrypt }; SymCryptRunProcessBase( const QString & class_, const QString & program, const QString & keyFile, const QString& options, Operation op, QObject * parent=0, const char * name=0 ); ~SymCryptRunProcessBase(); bool launch( const QByteArray & input, RunMode rm=NotifyOnExit ); const QByteArray & output() const { return mOutput; } const QString & stderr() const { return mStderr; } public slots: /*! upgraded to slot */ void closeStdin() { KProcess::closeStdin(); } private slots: void slotReceivedStdout( KProcess *, char *, int ); void slotReceivedStderr( KProcess *, char *, int ); private: void addOptions(); QByteArray mInput; QByteArray mOutput; QString mStderr; const Operation mOperation; QString mOptions; }; }; #endif // __KLEO_BACKEND_CHIASMUS__SYMCRYPTRUNPROCESSBASE_H__ diff --git a/lib/kleo/cryptobackend.cpp b/lib/backends/kpgp/gpg1backend.h similarity index 73% copy from lib/kleo/cryptobackend.cpp copy to lib/backends/kpgp/gpg1backend.h index 6da71bc9e..f9413accf 100644 --- a/lib/kleo/cryptobackend.cpp +++ b/lib/backends/kpgp/gpg1backend.h @@ -1,36 +1,52 @@ -/* - kleo/cryptobackend.cpp +/* -*- mode: C++; c-file-style: "gnu" -*- + gpg1backend.h This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#include "cryptobackend.h" -const char Kleo::CryptoBackend::OpenPGP[] = "OpenPGP"; -const char Kleo::CryptoBackend::SMIME[] = "SMIME"; +#ifndef __KLEO_GPG1BACKEND_H__ +#define __KLEO_GPG1BACKEND_H__ + +#include "kpgpbackendbase.h" + +class QString; + +namespace Kleo { + + class GPG1Backend : public KpgpBackendBase { + public: + QString name() const; + QString displayName() const; + }; + +} + + +#endif // __KLEO_GPG1BACKEND_H__ diff --git a/lib/backends/kpgp/kpgpbackendbase.cpp b/lib/backends/kpgp/kpgpbackendbase.cpp new file mode 100644 index 000000000..2d4d17ab2 --- /dev/null +++ b/lib/backends/kpgp/kpgpbackendbase.cpp @@ -0,0 +1,111 @@ +/* -*- mode: C++; c-file-style: "gnu" -*- + kpgpbackendbase.cpp + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "kpgpbackendbase.h" + +#include "pgp2backend.h" +#include "pgp5backend.h" +#include "pgp6backend.h" +#include "gpg1backend.h" + +#include + +#include + +#include "kpgpwrapper.h" + +Kleo::KpgpBackendBase::KpgpBackendBase() + : Kleo::CryptoBackend(), + mOpenPGPProtocol( 0 ) +{ +} + +Kleo::KpgpBackendBase::~KpgpBackendBase() +{ + delete mOpenPGPProtocol; mOpenPGPProtocol = 0; +} + +QString Kleo::GPG1Backend::name() const { + return GPG1_BACKEND_NAME; +} + +QString Kleo::GPG1Backend::displayName() const { + return i18n("Kpgp/gpg"); +} + +QString Kleo::PGP2Backend::name() const { + return PGP2_BACKEND_NAME; +} + +QString Kleo::PGP2Backend::displayName() const { + return i18n("Kpgp/pgp v2"); +} + +QString Kleo::PGP5Backend::name() const { + return PGP5_BACKEND_NAME; +} + +QString Kleo::PGP5Backend::displayName() const { + return i18n("Kpgp/pgp v5"); +} + +QString Kleo::PGP6Backend::name() const { + return PGP6_BACKEND_NAME; +} + +QString Kleo::PGP6Backend::displayName() const { + return i18n("Kpgp/pgp v6"); +} + +static const QString notSupported() { + return i18n("This backend does not support S/MIME"); +} + +bool Kleo::KpgpBackendBase::checkForOpenPGP( QString * /*reason*/ ) const { + return true; +} + +bool Kleo::KpgpBackendBase::checkForSMIME( QString * reason ) const { + if ( reason ) *reason = notSupported(); + return false; +} + +Kleo::CryptoBackend::Protocol * Kleo::KpgpBackendBase::openpgp() const { + if ( !mOpenPGPProtocol ) + if ( checkForOpenPGP() ) + mOpenPGPProtocol = new KpgpWrapper( name() ); + return mOpenPGPProtocol; +} diff --git a/lib/backends/qgpgme/qgpgmebackend.h b/lib/backends/kpgp/kpgpbackendbase.h similarity index 64% copy from lib/backends/qgpgme/qgpgmebackend.h copy to lib/backends/kpgp/kpgpbackendbase.h index 44301c683..854e800c3 100644 --- a/lib/backends/qgpgme/qgpgmebackend.h +++ b/lib/backends/kpgp/kpgpbackendbase.h @@ -1,82 +1,73 @@ /* -*- mode: C++; c-file-style: "gnu" -*- - qgpgmebackend.h + kpgpbackendbase.h This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2004,2005 Klarälvdalens Datakonsult AB + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#ifndef __KLEO_QGPGMEBACKEND_H__ -#define __KLEO_QGPGMEBACKEND_H__ +#ifndef __KLEO_KPGPBACKENDBASE_H__ +#define __KLEO_KPGPBACKENDBASE_H__ #include "kleo/cryptobackend.h" -class CryptPlugWrapper; +#define GPG1_BACKEND_NAME "Kpgp/gpg1" +#define PGP2_BACKEND_NAME "Kpgp/pgp2" +#define PGP5_BACKEND_NAME "Kpgp/pgp5" +#define PGP6_BACKEND_NAME "Kpgp/pgp6" namespace Kleo { class CryptoConfig; } -class QGpgMECryptoConfig; class QString; +class KpgpWrapper; namespace Kleo { - class QGpgMEBackend : public Kleo::CryptoBackend { + class KpgpBackendBase : public Kleo::CryptoBackend { public: - QGpgMEBackend(); - ~QGpgMEBackend(); - - QString name() const; - QString displayName() const; - - CryptoConfig * config() const; + KpgpBackendBase(); + ~KpgpBackendBase(); + CryptoConfig * config() const { return 0; } Protocol * openpgp() const; - Protocol * smime() const; - Protocol * protocol( const char * name ) const; - - bool checkForOpenPGP( QString * reason=0 ) const; - bool checkForSMIME( QString * reason=0 ) const; - bool checkForProtocol( const char * name, QString * reason ) const; + Protocol * smime() const { return 0; } bool supportsOpenPGP() const { return true; } - bool supportsSMIME() const { return true; } - bool supportsProtocol( const char * name ) const; - - const char * enumerateProtocols( int i ) const; + bool supportsSMIME() const { return false; } + bool checkForOpenPGP( QString * reason=0 ) const; + bool checkForSMIME( QString * reason=0 ) const; private: - mutable QGpgMECryptoConfig * mCryptoConfig; - mutable CryptPlugWrapper * mOpenPGPProtocol; - mutable CryptPlugWrapper * mSMIMEProtocol; + mutable KpgpWrapper * mOpenPGPProtocol; }; } -#endif // __KLEO_QGPGMEBACKEND_H__ +#endif // __KLEO_KPGPBACKENDBASE_H__ diff --git a/lib/backends/kpgp/kpgpkeylistjob.cpp b/lib/backends/kpgp/kpgpkeylistjob.cpp new file mode 100644 index 000000000..4c328adee --- /dev/null +++ b/lib/backends/kpgp/kpgpkeylistjob.cpp @@ -0,0 +1,303 @@ +/* + kpgpkeylistjob.cpp + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Ingo Kloecker + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "kpgpkeylistjob.h" + +#include +#include + +#include +#include + +#include + +#include + +#include +#include +#include + +Kleo::KpgpKeyListJob::KpgpKeyListJob( Kpgp::Base * pgpBase ) + : KeyListJob( 0, "Kleo::KpgpKeyListJob" ), + mPgpBase( pgpBase ) +{ +} + +Kleo::KpgpKeyListJob::~KpgpKeyListJob() { +} + +// the following function is a verbatim copy from gpgme/key.c +static char * +set_user_id_part (char *tail, const char *buf, size_t len) +{ + while (len && (buf[len - 1] == ' ' || buf[len - 1] == '\t')) + len--; + for (; len; len--) + *tail++ = *buf++; + *tail++ = 0; + return tail; +} + +// the following function is a verbatim copy from gpgme/key.c +static void +parse_user_id (char *src, char **name, char **email, + char **comment, char *tail) +{ + const char *start = NULL; + int in_name = 0; + int in_email = 0; + int in_comment = 0; + + while (*src) + { + if (in_email) + { + if (*src == '<') + /* Not legal but anyway. */ + in_email++; + else if (*src == '>') + { + if (!--in_email && !*email) + { + *email = tail; + tail = set_user_id_part (tail, start, src - start); + } + } + } + else if (in_comment) + { + if (*src == '(') + in_comment++; + else if (*src == ')') + { + if (!--in_comment && !*comment) + { + *comment = tail; + tail = set_user_id_part (tail, start, src - start); + } + } + } + else if (*src == '<') + { + if (in_name) + { + if (!*name) + { + *name = tail; + tail = set_user_id_part (tail, start, src - start); + } + in_name = 0; + } + in_email = 1; + start = src + 1; + } + else if (*src == '(') + { + if (in_name) + { + if (!*name) + { + *name = tail; + tail = set_user_id_part (tail, start, src - start); + } + in_name = 0; + } + in_comment = 1; + start = src + 1; + } + else if (!in_name && *src != ' ' && *src != '\t') + { + in_name = 1; + start = src; + } + src++; + } + + if (in_name) + { + if (!*name) + { + *name = tail; + tail = set_user_id_part (tail, start, src - start); + } + } + + /* Let unused parts point to an EOS. */ + tail--; + if (!*name) + *name = tail; + if (!*email) + *email = tail; + if (!*comment) + *comment = tail; +} + +gpgme_user_id_t KpgpUserID2GPGMEUserID( const Kpgp::UserID * kUserId ) +{ + // inspired by _gpgme_key_append_name + + const QCString text = kUserId->text().utf8(); + const int src_len = text.length(); + + gpgme_user_id_t uid; + /* Allocate enough memory for the _gpgme_user_id struct, for the actual user + id (the text) and for the parsed version. */ + uid = (gpgme_user_id_t) malloc( sizeof( *uid ) + 2 * src_len + 3 ); + memset( uid, 0, sizeof *uid ); + uid->revoked = kUserId->revoked(); + uid->invalid = kUserId->invalid(); + uid->validity = (gpgme_validity_t) kUserId->validity(); + + uid->uid = ((char *) uid) + sizeof (*uid); + char *dst = uid->uid; + memcpy( dst, text.data(), src_len + 1 ); + + dst += src_len + 1; + parse_user_id( uid->uid, &uid->name, &uid->email, + &uid->comment, dst ); + + return uid; +} + +gpgme_subkey_t KpgpSubkey2GPGMESubKey( const Kpgp::Subkey * kSubkey ) +{ + gpgme_subkey_t subkey; + + const QCString fpr = kSubkey->fingerprint(); + const unsigned int fpr_len = fpr.length(); + const QCString keyId = kSubkey->longKeyID(); + + subkey = (gpgme_subkey_t) calloc( 1, sizeof( *subkey ) + fpr_len + 1 ); + subkey->revoked = kSubkey->revoked(); + subkey->expired = kSubkey->expired(); + subkey->disabled = kSubkey->disabled(); + subkey->invalid = kSubkey->invalid(); + subkey->can_encrypt = kSubkey->canEncrypt(); + subkey->can_sign = kSubkey->canSign(); + subkey->can_certify = kSubkey->canCertify(); + subkey->secret = kSubkey->secret(); + subkey->pubkey_algo = (gpgme_pubkey_algo_t) kSubkey->keyAlgorithm(); + subkey->length = kSubkey->keyLength(); + subkey->keyid = subkey->_keyid; + memcpy( subkey->_keyid, keyId.data(), keyId.length() + 1 ); + subkey->fpr = ((char *) subkey) + sizeof( *subkey ); + memcpy( subkey->fpr, fpr.data(), fpr_len + 1 ); + subkey->timestamp = kSubkey->creationDate(); + subkey->expires = kSubkey->expirationDate(); + + return subkey; +} + +gpgme_key_t KpgpKey2gpgme_key( const Kpgp::Key * kKey ) +{ + gpgme_key_t key; + + key = (gpgme_key_t) calloc( 1, sizeof( *key ) ); + key->revoked = kKey->revoked(); + key->expired = kKey->expired(); + key->disabled = kKey->disabled(); + key->invalid = kKey->invalid(); + key->can_encrypt = kKey->canEncrypt(); + key->can_sign = kKey->canSign(); + key->can_certify = kKey->canCertify(); + key->secret = kKey->secret(); + key->protocol = GPGME_PROTOCOL_OpenPGP; + key->owner_trust = GPGME_VALIDITY_UNKNOWN; // FIXME? + + Kpgp::UserIDList kUserIDs = kKey->userIDs(); + for ( Kpgp::UserIDListIterator it( kUserIDs ); it.current(); ++it ) { + gpgme_user_id_t uid = KpgpUserID2GPGMEUserID( *it ); + if ( !key->uids ) + key->uids = uid; + if ( key->_last_uid ) + key->_last_uid->next = uid; + key->_last_uid = uid; + } + + Kpgp::SubkeyList kSubkeys = kKey->subkeys(); + for ( Kpgp::SubkeyListIterator it( kSubkeys ); it.current(); ++it ) { + gpgme_subkey_t subkey = KpgpSubkey2GPGMESubKey( *it ); + if (!key->subkeys) + key->subkeys = subkey; + if (key->_last_subkey) + key->_last_subkey->next = subkey; + key->_last_subkey = subkey; + } + + return key; +} + +GpgME::Error Kleo::KpgpKeyListJob::start( const QStringList & patterns, + bool secretOnly ) { + mPatterns = patterns; + mSecretOnly = secretOnly; + QTimer::singleShot( 0, this, SLOT( slotDoIt() ) ); + return GpgME::Error( 0 ); +} + +void Kleo::KpgpKeyListJob::slotDoIt() { + std::vector keys; + GpgME::KeyListResult res = exec( mPatterns, mSecretOnly, keys ); + for ( std::vector::const_iterator it = keys.begin(); + it != keys.end(); ++it ) + emit nextKey( *it ); + emit done(); + emit result( res ); + deleteLater(); +} + +GpgME::KeyListResult Kleo::KpgpKeyListJob::exec( const QStringList & patterns, + bool secretOnly, + std::vector & keys ) { + Kpgp::KeyList kKeys; + if ( secretOnly ) + kKeys = mPgpBase->secretKeys( patterns ); + else + kKeys = mPgpBase->publicKeys( patterns ); + + keys.clear(); + for ( Kpgp::KeyListIterator it( kKeys ); it.current(); ++it ) { + keys.push_back( GpgME::Key( KpgpKey2gpgme_key(*it), true ) ); + } + + _gpgme_op_keylist_result res; + res.truncated = 0; // key list is not truncated + res._unused = 0; + + return GpgME::KeyListResult( GpgME::Error( 0 ), res ); +} + +#include "kpgpkeylistjob.moc" diff --git a/lib/backends/chiasmus/chiasmuslibrary.h b/lib/backends/kpgp/kpgpkeylistjob.h similarity index 57% copy from lib/backends/chiasmus/chiasmuslibrary.h copy to lib/backends/kpgp/kpgpkeylistjob.h index 1759b4fc7..779680c2d 100644 --- a/lib/backends/chiasmus/chiasmuslibrary.h +++ b/lib/backends/kpgp/kpgpkeylistjob.h @@ -1,68 +1,79 @@ -/* -*- mode: C++; c-file-style: "gnu" -*- - chiasmuslibrary.h +/* -*- mode: C++ -*- + kpgpkeylistjob.h This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + Copyright (c) 2004 Ingo Kloecker Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ +#ifndef __KLEO_KPGPKEYLISTJOB_H__ +#define __KLEO_KPGPKEYLISTJOB_H__ -#ifndef __KLEO_CHIASMUSLIBRARY_H__ -#define __KLEO_CHIASMUSLIBRARY_H__ +#include -#include -#include +#include -class KLibrary; +namespace GpgME { + class Error; + class Context; + class Key; +} + +namespace Kpgp { + class Base; +} namespace Kleo { - /** - @short small helper class to load xia.o through xia.so and make - the functionality available. - */ - class ChiasmusLibrary { - ChiasmusLibrary(); - ~ChiasmusLibrary(); + class KpgpKeyListJob : public KeyListJob { + Q_OBJECT public: - static const ChiasmusLibrary * instance(); - static void deleteInstance(); + KpgpKeyListJob( Kpgp::Base * pgpBase ); + ~KpgpKeyListJob(); - int perform( const QValueVector & args ) const; - private: - typedef int ( *main_func )( int, char** ); - main_func chiasmus( QString * reason=0 ) const; + /*! \reimp from KeyListJob */ + GpgME::Error start( const QStringList & patterns, bool secretOnly ); + + /*! \reimp from KeyListJob */ + GpgME::KeyListResult exec( const QStringList & patterns, bool secretOnly, + std::vector & keys ); + + /*! \reimp from Job */ + void slotCancel() { /*FIXME*/ } + + private slots: + void slotDoIt(); private: - static ChiasmusLibrary * self; - mutable KLibrary * mXiaLibrary; + Kpgp::Base * mPgpBase; + QStringList mPatterns; + bool mSecretOnly; }; } - -#endif // __KLEO_CHIASMUSLIBRARY_H__ +#endif // __KLEO_KPGPKEYLISTJOB_H__ diff --git a/lib/backends/kpgp/kpgpwrapper.cpp b/lib/backends/kpgp/kpgpwrapper.cpp new file mode 100644 index 000000000..20d885dd5 --- /dev/null +++ b/lib/backends/kpgp/kpgpwrapper.cpp @@ -0,0 +1,173 @@ +/* -*- mode: C++; c-file-style: "gnu" -*- + kpgpwrapper.cpp + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Ingo Kloecker + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "kpgpwrapper.h" + +#include "kpgpbackendbase.h" + +#include + +#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include + +KpgpWrapper::KpgpWrapper( const QString & name ) + : mName( name ), + mPgpBase( 0 ) +{ + +} + +KpgpWrapper::~KpgpWrapper() +{ + +} + +QString KpgpWrapper::name() const +{ + return mName; +} + +QString KpgpWrapper::displayName() const +{ + return mName; +} + +Kleo::KeyListJob * KpgpWrapper::keyListJob( bool /*remote*/, + bool /*includeSigs*/, + bool /*validate*/ ) const +{ + return new Kleo::KpgpKeyListJob( pgpBase() ); +} + +Kleo::EncryptJob * KpgpWrapper::encryptJob( bool /*armor*/, + bool /*textmode*/ ) const +{ + return 0; +} + +Kleo::DecryptJob * KpgpWrapper::decryptJob() const +{ + return 0; +} + +Kleo::SignJob * KpgpWrapper::signJob( bool /*armor*/, bool /*textMode*/ ) const +{ + return 0; +} + +Kleo::VerifyDetachedJob * KpgpWrapper::verifyDetachedJob( bool /*textmode*/ ) const +{ + return 0; +} + +Kleo::VerifyOpaqueJob * KpgpWrapper::verifyOpaqueJob( bool /*textmode*/ ) const +{ + return 0; +} + +Kleo::KeyGenerationJob * KpgpWrapper::keyGenerationJob() const +{ + return 0; +} + +Kleo::ImportJob * KpgpWrapper::importJob() const +{ + return 0; +} + +Kleo::ExportJob * KpgpWrapper::publicKeyExportJob( bool /*armor*/ ) const +{ + return 0; +} + +Kleo::ExportJob * KpgpWrapper::secretKeyExportJob( bool /*armor*/ ) const +{ + return 0; +} + +Kleo::DownloadJob * KpgpWrapper::downloadJob( bool /*armor*/ ) const +{ + return 0; +} + +Kleo::DeleteJob * KpgpWrapper::deleteJob() const +{ + return 0; +} + +Kleo::SignEncryptJob * KpgpWrapper::signEncryptJob( bool /*armor*/, + bool /*textMode*/ ) const +{ + return 0; +} + +Kleo::DecryptVerifyJob * KpgpWrapper::decryptVerifyJob( bool /*textmode*/ ) const +{ + return 0; +} + +Kleo::RefreshKeysJob * KpgpWrapper::refreshKeysJob() const +{ + return 0; +} + +Kpgp::Base * KpgpWrapper::pgpBase() const +{ + if ( !mPgpBase ) { + if ( name() == GPG1_BACKEND_NAME ) + mPgpBase = new Kpgp::BaseG(); + else if ( name() == PGP2_BACKEND_NAME ) + mPgpBase = new Kpgp::Base2(); + else if ( name() == PGP5_BACKEND_NAME ) + mPgpBase = new Kpgp::Base5(); + else if ( name() == PGP6_BACKEND_NAME ) + mPgpBase = new Kpgp::Base6(); + } + return mPgpBase; +} diff --git a/lib/backends/kpgp/kpgpwrapper.h b/lib/backends/kpgp/kpgpwrapper.h new file mode 100644 index 000000000..182661ec4 --- /dev/null +++ b/lib/backends/kpgp/kpgpwrapper.h @@ -0,0 +1,97 @@ +/* -*- mode: C++; c-file-style: "gnu" -*- + kpgpwrapper.h + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Ingo Kloecker + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifndef __KLEO_KPGPWRAPPER_H__ +#define __KLEO_KPGPWRAPPER_H__ + +#include + +#include + +namespace Kleo { + class KeyListJob; + class EncryptJob; + class DecryptJob; + class SignJob; + class VerifyDetachedJob; + class VerifyOpaqueJob; + class KeyGenerationJob; + class ImportJob; + class ExportJob; + class DownloadJob; + class DeleteJob; + class SignEncryptJob; + class DecryptVerifyJob; + class CryptoConfig; + class RefreshKeysJob; +} + +namespace Kpgp { + class Base; +} + +class KpgpWrapper : public Kleo::CryptoBackend::Protocol { +public: + KpgpWrapper( const QString & name ); + ~KpgpWrapper(); + + QString name() const; + + QString displayName() const; + + Kleo::KeyListJob * keyListJob( bool remote=false, bool includeSigs=false, + bool validate=false ) const; + Kleo::EncryptJob * encryptJob( bool armor=false, bool textmode=false ) const; + Kleo::DecryptJob * decryptJob() const; + Kleo::SignJob * signJob( bool armor=false, bool textMode=false ) const; + Kleo::VerifyDetachedJob * verifyDetachedJob( bool textmode=false) const; + Kleo::VerifyOpaqueJob * verifyOpaqueJob( bool textmode=false ) const; + Kleo::KeyGenerationJob * keyGenerationJob() const; + Kleo::ImportJob * importJob() const; + Kleo::ExportJob * publicKeyExportJob( bool armor=false ) const; + Kleo::ExportJob * secretKeyExportJob( bool armor=false ) const; + Kleo::DownloadJob * downloadJob( bool armor=false ) const; + Kleo::DeleteJob * deleteJob() const; + Kleo::SignEncryptJob * signEncryptJob( bool armor=false, + bool textMode=false ) const; + Kleo::DecryptVerifyJob * decryptVerifyJob( bool textmode=false ) const; + Kleo::RefreshKeysJob * refreshKeysJob() const; + +private: + Kpgp::Base * pgpBase() const; + +private: + QString mName; + mutable Kpgp::Base * mPgpBase; +}; + +#endif // __KLEO_KPGPWRAPPER_H__ diff --git a/lib/kleo/cryptobackend.cpp b/lib/backends/kpgp/pgp2backend.h similarity index 73% copy from lib/kleo/cryptobackend.cpp copy to lib/backends/kpgp/pgp2backend.h index 6da71bc9e..fc053a20c 100644 --- a/lib/kleo/cryptobackend.cpp +++ b/lib/backends/kpgp/pgp2backend.h @@ -1,36 +1,52 @@ -/* - kleo/cryptobackend.cpp +/* -*- mode: C++; c-file-style: "gnu" -*- + pgp2backend.h This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#include "cryptobackend.h" -const char Kleo::CryptoBackend::OpenPGP[] = "OpenPGP"; -const char Kleo::CryptoBackend::SMIME[] = "SMIME"; +#ifndef __KLEO_PGP2BACKEND_H__ +#define __KLEO_PGP2BACKEND_H__ + +#include "kpgpbackendbase.h" + +class QString; + +namespace Kleo { + + class PGP2Backend : public KpgpBackendBase { + public: + QString name() const; + QString displayName() const; + }; + +} + + +#endif // __KLEO_PGP2BACKEND_H__ diff --git a/lib/kleo/cryptobackend.cpp b/lib/backends/kpgp/pgp5backend.h similarity index 73% copy from lib/kleo/cryptobackend.cpp copy to lib/backends/kpgp/pgp5backend.h index 6da71bc9e..bf323b6fb 100644 --- a/lib/kleo/cryptobackend.cpp +++ b/lib/backends/kpgp/pgp5backend.h @@ -1,36 +1,52 @@ -/* - kleo/cryptobackend.cpp +/* -*- mode: C++; c-file-style: "gnu" -*- + pgp5backend.h This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#include "cryptobackend.h" -const char Kleo::CryptoBackend::OpenPGP[] = "OpenPGP"; -const char Kleo::CryptoBackend::SMIME[] = "SMIME"; +#ifndef __KLEO_PGP5BACKEND_H__ +#define __KLEO_PGP5BACKEND_H__ + +#include "kpgpbackendbase.h" + +class QString; + +namespace Kleo { + + class PGP5Backend : public KpgpBackendBase { + public: + QString name() const; + QString displayName() const; + }; + +} + + +#endif // __KLEO_PGP5BACKEND_H__ diff --git a/lib/kleo/cryptobackend.cpp b/lib/backends/kpgp/pgp6backend.h similarity index 73% copy from lib/kleo/cryptobackend.cpp copy to lib/backends/kpgp/pgp6backend.h index 6da71bc9e..827cf239b 100644 --- a/lib/kleo/cryptobackend.cpp +++ b/lib/backends/kpgp/pgp6backend.h @@ -1,36 +1,52 @@ -/* - kleo/cryptobackend.cpp +/* -*- mode: C++; c-file-style: "gnu" -*- + pgp6backend.h This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#include "cryptobackend.h" -const char Kleo::CryptoBackend::OpenPGP[] = "OpenPGP"; -const char Kleo::CryptoBackend::SMIME[] = "SMIME"; +#ifndef __KLEO_PGP6BACKEND_H__ +#define __KLEO_PGP6BACKEND_H__ + +#include "kpgpbackendbase.h" + +class QString; + +namespace Kleo { + + class PGP6Backend : public KpgpBackendBase { + public: + QString name() const; + QString displayName() const; + }; + +} + + +#endif // __KLEO_PGP6BACKEND_H__ diff --git a/lib/backends/qgpgme/gnupgprocessbase.cpp b/lib/backends/qgpgme/gnupgprocessbase.cpp new file mode 100644 index 000000000..2d3ca7409 --- /dev/null +++ b/lib/backends/qgpgme/gnupgprocessbase.cpp @@ -0,0 +1,198 @@ +/* + gnupgprocessbase.cpp + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#include "gnupgprocessbase.h" + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +struct Kleo::GnuPGProcessBase::Private { + Private() : useStatusFD( false ), statnot( 0 ) { + statusFD[0] = statusFD[1] = -1; + } + + bool useStatusFD; + int statusFD[2]; + QSocketNotifier * statnot; + QCString statusBuffer; +}; + + +Kleo::GnuPGProcessBase::GnuPGProcessBase( QObject * parent, const char * name ) + : KProcess( parent, name ) +{ + d = new Private(); +} + +Kleo::GnuPGProcessBase::~GnuPGProcessBase() { + delete d; d = 0; +} + +void Kleo::GnuPGProcessBase::setUseStatusFD( bool use ) { + assert( d ); + d->useStatusFD = use; +} + +bool Kleo::GnuPGProcessBase::start( RunMode runmode, Communication comm ) { + if ( d->useStatusFD ) { + // set up the status-fd. This should be in setupCommunication(), + // but then it's too late: we need the fd of the pipe to pass it + // as argument to the --status-fd option: + // PENDING(marc) find out why KProcess uses both pipe() and socketpair()... + if ( ::pipe( d->statusFD ) < 0 ) { + kdDebug( 5150 ) << "Kleo::GnuPGProcessBase::start: pipe(2) failed: " << perror << endl; + return false; + } + ::fcntl( d->statusFD[0], F_SETFD, FD_CLOEXEC ); + ::fcntl( d->statusFD[1], F_SETFD, FD_CLOEXEC ); + if ( !arguments.empty() ) { + QValueList::iterator it = arguments.begin(); + ++it; + arguments.insert( it, "--status-fd" ); + char buf[25]; + sprintf( buf, "%d", d->statusFD[1] ); + arguments.insert( it, buf ); + arguments.insert( it, "--no-tty" ); + //arguments.insert( it, "--enable-progress-filter" ); // gpgsm doesn't know this + } + } + return KProcess::start( runmode, comm ); +} + +int Kleo::GnuPGProcessBase::setupCommunication( Communication comm ) { + if ( int ok = KProcess::setupCommunication( comm ) ) + return ok; + if ( d->useStatusFD ) { + // base class impl returned error, so close our fd's, too + ::close( d->statusFD[0] ); + ::close( d->statusFD[1] ); + d->statusFD[0] = d->statusFD[1] = -1; + } + return 0; // Error +} + +int Kleo::GnuPGProcessBase::commSetupDoneP() { + if ( d->useStatusFD ) { + ::close( d->statusFD[1] ); // close the input end of the pipe, we're the reader + d->statnot = new QSocketNotifier( d->statusFD[0], QSocketNotifier::Read, this ); + connect( d->statnot, SIGNAL(activated(int)), SLOT(slotChildStatus(int)) ); + } + return KProcess::commSetupDoneP(); +} + +int Kleo::GnuPGProcessBase::commSetupDoneC() { + if ( d->useStatusFD ) + ::fcntl( d->statusFD[1], F_SETFD, 0 ); + return KProcess::commSetupDoneC(); +} + +void Kleo::GnuPGProcessBase::slotChildStatus( int fd ) { + if ( !childStatus(fd) ) + closeStatus(); +} + +bool Kleo::GnuPGProcessBase::closeStatus() { + if ( !d->useStatusFD ) + return false; + d->useStatusFD = false; + delete d->statnot; d->statnot = 0; + ::close( d->statusFD[0] ); d->statusFD[0] = -1; + return true; +} + +int Kleo::GnuPGProcessBase::childStatus( int fd ) { + char buf[1024]; + const int len = ::read( fd, buf, sizeof(buf)-1 ); + if ( len > 0 ) { + buf[len] = 0; + d->statusBuffer += buf; + parseStatusOutput(); + } + return len; +} + +static QString fromHexEscapedUtf8( const QCString & str ) { + return KURL::decode_string( str.data(), 106 /* utf-8 */ ); +} + +void Kleo::GnuPGProcessBase::parseStatusOutput() { + static const char startToken[] = "[GNUPG:] "; + static const int startTokenLen = sizeof startToken / sizeof *startToken - 1; + + int lineStart = 0; + for ( int lineEnd = d->statusBuffer.find( '\n' ) ; lineEnd >= 0 ; lineEnd = d->statusBuffer.find( '\n', lineStart = lineEnd+1 ) ) { + // get next line: + const QCString line = d->statusBuffer.mid( lineStart, lineEnd - lineStart ).stripWhiteSpace(); + if ( line.isEmpty() ) + continue; + // check status token + if ( line.left( startTokenLen ) != startToken ) { + kdDebug( 5150 ) << "Kleo::GnuPGProcessBase::childStatus: status-fd protocol error: line doesn't begin with \"" + << startToken << "\"" << endl; + continue; + } + // remove status token: + const QCString command = line.mid( startTokenLen ).simplifyWhiteSpace() + ' '; + if ( command == " " ) { + kdDebug( 5150 ) << "Kleo::GnuPGProcessBase::childStatus: status-fd protocol error: line without content." << endl; + continue; + } + // split into base and args + QString cmd; + QStringList args; + int tagStart = 0; + for ( int tagEnd = command.find( ' ' ) ; tagEnd >= 0 ; tagEnd = command.find( ' ', tagStart = tagEnd+1 ) ) { + const QCString tag = command.mid( tagStart, tagEnd - tagStart ); + if ( cmd.isNull() ) + cmd = fromHexEscapedUtf8( tag ); + else + args.push_back( fromHexEscapedUtf8( tag ) ); + } + emit status( this, cmd, args ); + } + d->statusBuffer = d->statusBuffer.mid( lineStart ); +} + +void Kleo::GnuPGProcessBase::virtual_hook( int id, void * data ) { + KProcess::virtual_hook( id, data ); +} + +#include "gnupgprocessbase.moc" diff --git a/lib/backends/chiasmus/chiasmuslibrary.h b/lib/backends/qgpgme/gnupgprocessbase.h similarity index 51% copy from lib/backends/chiasmus/chiasmuslibrary.h copy to lib/backends/qgpgme/gnupgprocessbase.h index 1759b4fc7..73e31e295 100644 --- a/lib/backends/chiasmus/chiasmuslibrary.h +++ b/lib/backends/qgpgme/gnupgprocessbase.h @@ -1,68 +1,91 @@ -/* -*- mode: C++; c-file-style: "gnu" -*- - chiasmuslibrary.h +/* + gnupgprocessbase.h This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ +#ifndef __KLEO_GNUPGPROCESSBASE_H__ +#define __KLEO_GNUPGPROCESSBASE_H__ -#ifndef __KLEO_CHIASMUSLIBRARY_H__ -#define __KLEO_CHIASMUSLIBRARY_H__ - -#include -#include - -class KLibrary; +#include namespace Kleo { /** - @short small helper class to load xia.o through xia.so and make - the functionality available. - */ - class ChiasmusLibrary { - ChiasmusLibrary(); - ~ChiasmusLibrary(); + * @short a base class for GPG and GPGSM processes. + * + * This KProcess subclass implements the status-fd handling common + * to GPG and GPGSM. + * + * @author Marc Mutz + */ + class GnuPGProcessBase : public KProcess { + Q_OBJECT public: - static const ChiasmusLibrary * instance(); - static void deleteInstance(); + GnuPGProcessBase( QObject * parent=0, const char * name=0 ); + ~GnuPGProcessBase(); + + void setUseStatusFD( bool use ); + + /*! reimplementation */ + bool start( RunMode runmode, Communication comm ); + + bool closeStatus(); + + signals: + void status( Kleo::GnuPGProcessBase * proc, const QString & type, const QStringList & args ); + + protected: + /*! reimplementation */ + int setupCommunication( Communication comm ); + /*! reimplementation */ + int commSetupDoneP(); + /*! reimplementation */ + int commSetupDoneC(); + + int childStatus( int fd ); + + + private slots: + void slotChildStatus( int fd ); - int perform( const QValueVector & args ) const; private: - typedef int ( *main_func )( int, char** ); - main_func chiasmus( QString * reason=0 ) const; + void parseStatusOutput(); private: - static ChiasmusLibrary * self; - mutable KLibrary * mXiaLibrary; + class Private; + Private * d; + protected: + /*! reimplementation */ + void virtual_hook( int id, void * data ); }; } - -#endif // __KLEO_CHIASMUSLIBRARY_H__ +#endif // __KLEO_GNUPGPROCESSBASE_H__ diff --git a/lib/backends/qgpgme/qgpgmebackend.cpp b/lib/backends/qgpgme/qgpgmebackend.cpp index 1b68d08c2..de05eb160 100644 --- a/lib/backends/qgpgme/qgpgmebackend.cpp +++ b/lib/backends/qgpgme/qgpgmebackend.cpp @@ -1,153 +1,153 @@ /* -*- mode: C++; c-file-style: "gnu" -*- qgpgmebackend.cpp This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004,2005 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifdef HAVE_CONFIG_H #include #endif #include "qgpgmebackend.h" #include "qgpgmecryptoconfig.h" #include "cryptplugwrapper.h" #include #include #include #include #include #include Kleo::QGpgMEBackend::QGpgMEBackend() : Kleo::CryptoBackend(), mCryptoConfig( 0 ), mOpenPGPProtocol( 0 ), mSMIMEProtocol( 0 ) { } Kleo::QGpgMEBackend::~QGpgMEBackend() { delete mCryptoConfig; mCryptoConfig = 0; delete mOpenPGPProtocol; mOpenPGPProtocol = 0; delete mSMIMEProtocol; mSMIMEProtocol = 0; } QString Kleo::QGpgMEBackend::name() const { return "gpgme"; } QString Kleo::QGpgMEBackend::displayName() const { return i18n( "GpgME" ); } Kleo::CryptoConfig * Kleo::QGpgMEBackend::config() const { if ( !mCryptoConfig ) { static bool hasGpgConf = !KStandardDirs::findExe( "gpgconf" ).isEmpty(); if ( hasGpgConf ) mCryptoConfig = new QGpgMECryptoConfig(); } return mCryptoConfig; } static bool check( GpgME::Context::Protocol proto, QString * reason ) { if ( !GpgME::checkEngine( proto ) ) return true; if ( !reason ) return false; // error, check why: const GpgME::EngineInfo ei = GpgME::engineInfo( proto ); if ( ei.isNull() ) *reason = i18n("GPGME was compiled without support for %1.").arg( proto == GpgME::Context::CMS ? "S/MIME" : "OpenPGP" ); else if ( ei.fileName() && !ei.version() ) *reason = i18n("Engine %1 is not installed properly.").arg( QFile::decodeName( ei.fileName() ) ); else if ( ei.fileName() && ei.version() && ei.requiredVersion() ) *reason = i18n("Engine %1 version %2 installed, " "but at least version %3 is required.") .arg( QFile::decodeName( ei.fileName() ), ei.version(), ei.requiredVersion() ); else *reason = i18n("Unknown problem with engine for protocol %1.").arg( proto == GpgME::Context::CMS ? "S/MIME" : "OpenPGP" ); return false; } bool Kleo::QGpgMEBackend::checkForOpenPGP( QString * reason ) const { return check( GpgME::Context::OpenPGP, reason ); } bool Kleo::QGpgMEBackend::checkForSMIME( QString * reason ) const { return check( GpgME::Context::CMS, reason ); } bool Kleo::QGpgMEBackend::checkForProtocol( const char * name, QString * reason ) const { if ( qstricmp( name, OpenPGP ) == 0 ) return check( GpgME::Context::OpenPGP, reason ); if ( qstricmp( name, SMIME ) == 0 ) return check( GpgME::Context::CMS, reason ); if ( reason ) *reason = i18n( "Unsupported protocol \"%1\"" ).arg( name ); return false; } Kleo::CryptoBackend::Protocol * Kleo::QGpgMEBackend::openpgp() const { if ( !mOpenPGPProtocol ) if ( checkForOpenPGP() ) mOpenPGPProtocol = new CryptPlugWrapper( "gpg", "openpgp" ); return mOpenPGPProtocol; } Kleo::CryptoBackend::Protocol * Kleo::QGpgMEBackend::smime() const { if ( !mSMIMEProtocol ) if ( checkForSMIME() ) mSMIMEProtocol = new CryptPlugWrapper( "gpgsm", "smime" ); return mSMIMEProtocol; } Kleo::CryptoBackend::Protocol * Kleo::QGpgMEBackend::protocol( const char * name ) const { if ( qstricmp( name, OpenPGP ) == 0 ) return openpgp(); if ( qstricmp( name, SMIME ) == 0 ) return smime(); return 0; } bool Kleo::QGpgMEBackend::supportsProtocol( const char * name ) const { return qstricmp( name, OpenPGP ) == 0 || qstricmp( name, SMIME ); } const char * Kleo::QGpgMEBackend::enumerateProtocols( int i ) const { switch ( i ) { case 0: return OpenPGP; case 1: return SMIME; default: return 0; } } diff --git a/lib/backends/qgpgme/qgpgmebackend.h b/lib/backends/qgpgme/qgpgmebackend.h index 44301c683..fae2dd68e 100644 --- a/lib/backends/qgpgme/qgpgmebackend.h +++ b/lib/backends/qgpgme/qgpgmebackend.h @@ -1,82 +1,82 @@ /* -*- mode: C++; c-file-style: "gnu" -*- qgpgmebackend.h This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004,2005 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifndef __KLEO_QGPGMEBACKEND_H__ #define __KLEO_QGPGMEBACKEND_H__ #include "kleo/cryptobackend.h" class CryptPlugWrapper; namespace Kleo { class CryptoConfig; } class QGpgMECryptoConfig; class QString; namespace Kleo { class QGpgMEBackend : public Kleo::CryptoBackend { public: QGpgMEBackend(); ~QGpgMEBackend(); QString name() const; QString displayName() const; CryptoConfig * config() const; Protocol * openpgp() const; Protocol * smime() const; Protocol * protocol( const char * name ) const; bool checkForOpenPGP( QString * reason=0 ) const; bool checkForSMIME( QString * reason=0 ) const; bool checkForProtocol( const char * name, QString * reason ) const; bool supportsOpenPGP() const { return true; } bool supportsSMIME() const { return true; } bool supportsProtocol( const char * name ) const; const char * enumerateProtocols( int i ) const; private: mutable QGpgMECryptoConfig * mCryptoConfig; mutable CryptPlugWrapper * mOpenPGPProtocol; mutable CryptPlugWrapper * mSMIMEProtocol; }; } #endif // __KLEO_QGPGMEBACKEND_H__ diff --git a/lib/backends/qgpgme/qgpgmecryptoconfig.cpp b/lib/backends/qgpgme/qgpgmecryptoconfig.cpp index 90a5d62c9..f8aa068b3 100644 --- a/lib/backends/qgpgme/qgpgmecryptoconfig.cpp +++ b/lib/backends/qgpgme/qgpgmecryptoconfig.cpp @@ -1,831 +1,831 @@ /* qgpgmecryptoconfig.cpp This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #include "qgpgmecryptoconfig.h" #include #include #include #include #include #include #include #include #include #include // Just for the Q_ASSERT in the dtor. Not thread-safe, but who would // have 2 threads talking to gpgconf anyway? :) static bool s_duringClear = false; #define GPGCONF_FLAG_GROUP 1 #define GPGCONF_FLAG_OPTIONAL 2 #define GPGCONF_FLAG_LIST 4 #define GPGCONF_FLAG_RUNTIME 8 #define GPGCONF_FLAG_DEFAULT 16 // fixed default value available #define GPGCONF_FLAG_DEFAULT_DESC 32 // runtime default value available #define GPGCONF_FLAG_NOARG_DESC 64 // option with optional arg; special meaning if no arg set // Change size of mFlags bitfield if adding new values here QGpgMECryptoConfig::QGpgMECryptoConfig() : mComponents( 7 ), mParsed( false ) { mComponents.setAutoDelete( true ); } QGpgMECryptoConfig::~QGpgMECryptoConfig() { } void QGpgMECryptoConfig::runGpgConf( bool showErrors ) { // Run gpgconf --list-components to make the list of components KProcIO proc( QTextCodec::codecForName( "utf8" ) ); proc << "gpgconf"; // must be in the PATH proc << "--list-components"; QObject::connect( &proc, SIGNAL( readReady(KProcIO*) ), this, SLOT( slotCollectStdOut(KProcIO*) ) ); // run the process: int rc = 0; if ( !proc.start( KProcess::Block ) ) rc = -1; else rc = ( proc.normalExit() ) ? proc.exitStatus() : -2 ; // handle errors, if any (and if requested) if ( showErrors && rc != 0 ) { QString wmsg = i18n("Failed to execute gpgconf:
%1
"); if ( rc == -1 ) wmsg = wmsg.arg( i18n( "program not found" ) ); else if ( rc == -2 ) wmsg = wmsg.arg( i18n( "program cannot be executed" ) ); else wmsg = wmsg.arg( strerror(rc) ); kdWarning(5150) << wmsg << endl; // to see it from test_cryptoconfig.cpp KMessageBox::error(0, wmsg); } mParsed = true; } void QGpgMECryptoConfig::slotCollectStdOut( KProcIO* proc ) { QString line; int result; while( ( result = proc->readln(line) ) != -1 ) { //kdDebug(5150) << "GOT LINE:" << line << endl; // Format: NAME:DESCRIPTION QStringList lst = QStringList::split( ':', line, true ); if ( lst.count() >= 2 ) { mComponents.insert( lst[0], new QGpgMECryptoConfigComponent( this, lst[0], lst[1] ) ); } else { kdWarning(5150) << "Parse error on gpgconf --list-components output: " << line << endl; } } } QStringList QGpgMECryptoConfig::componentList() const { if ( !mParsed ) const_cast( this )->runGpgConf( true ); QDictIterator it( mComponents ); QStringList names; for( ; it.current(); ++it ) names.push_back( it.currentKey() ); return names; } Kleo::CryptoConfigComponent* QGpgMECryptoConfig::component( const QString& name ) const { if ( !mParsed ) const_cast( this )->runGpgConf( false ); return mComponents.find( name ); } void QGpgMECryptoConfig::sync( bool runtime ) { QDictIterator it( mComponents ); for( ; it.current(); ++it ) it.current()->sync( runtime ); } void QGpgMECryptoConfig::clear() { s_duringClear = true; mComponents.clear(); s_duringClear = false; mParsed = false; // next call to componentList/component will need to run gpgconf again } //// QGpgMECryptoConfigComponent::QGpgMECryptoConfigComponent( QGpgMECryptoConfig*, const QString& name, const QString& description ) : mGroups( 7 ), mName( name ), mDescription( description ) { mGroups.setAutoDelete( true ); runGpgConf(); } QGpgMECryptoConfigComponent::~QGpgMECryptoConfigComponent() { } void QGpgMECryptoConfigComponent::runGpgConf() { // Run gpgconf --list-options , and create all groups and entries for that component KProcIO proc( QTextCodec::codecForName( "utf8" ) ); proc << "gpgconf"; // must be in the PATH proc << "--list-options"; proc << mName; //kdDebug(5150) << "Running gpgconf --list-options " << mName << endl; QObject::connect( &proc, SIGNAL( readReady(KProcIO*) ), this, SLOT( slotCollectStdOut(KProcIO*) ) ); mCurrentGroup = 0; // run the process: int rc = 0; if ( !proc.start( KProcess::Block ) ) rc = -1; else rc = ( proc.normalExit() ) ? proc.exitStatus() : -1 ; if( rc != 0 ) // can happen when using the wrong version of gpg... kdWarning(5150) << "Running 'gpgconf --list-options " << mName << "' failed. " << strerror( rc ) << ", but try that command to see the real output" << endl; else { if ( mCurrentGroup && !mCurrentGroup->mEntries.isEmpty() ) // only add non-empty groups mGroups.insert( mCurrentGroupName, mCurrentGroup ); } } void QGpgMECryptoConfigComponent::slotCollectStdOut( KProcIO* proc ) { QString line; int result; while( ( result = proc->readln(line) ) != -1 ) { //kdDebug(5150) << "GOT LINE:" << line << endl; // Format: NAME:FLAGS:LEVEL:DESCRIPTION:TYPE:ALT-TYPE:ARGNAME:DEFAULT:ARGDEF:VALUE const QStringList lst = QStringList::split( ':', line, true ); if ( lst.count() >= 10 ) { const int flags = lst[1].toInt(); const int level = lst[2].toInt(); if ( level > 2 ) // invisible or internal -> skip it; continue; if ( flags & GPGCONF_FLAG_GROUP ) { if ( mCurrentGroup && !mCurrentGroup->mEntries.isEmpty() ) // only add non-empty groups mGroups.insert( mCurrentGroupName, mCurrentGroup ); //else // kdDebug(5150) << "Discarding empty group " << mCurrentGroupName << endl; mCurrentGroup = new QGpgMECryptoConfigGroup( lst[0], lst[3], level ); mCurrentGroupName = lst[0]; } else { // normal entry if ( !mCurrentGroup ) { // first toplevel entry -> create toplevel group mCurrentGroup = new QGpgMECryptoConfigGroup( "", QString::null, 0 ); mCurrentGroupName = ""; } mCurrentGroup->mEntries.insert( lst[0], new QGpgMECryptoConfigEntry( lst ) ); } } else { // This happens on lines like // dirmngr[31465]: error opening `/home/dfaure/.gnupg/dirmngr_ldapservers.conf': No such file or directory // so let's not bother the user with it. //kdWarning(5150) << "Parse error on gpgconf --list-options output: " << line << endl; } } } QStringList QGpgMECryptoConfigComponent::groupList() const { QDictIterator it( mGroups ); QStringList names; for( ; it.current(); ++it ) names.push_back( it.currentKey() ); return names; } Kleo::CryptoConfigGroup* QGpgMECryptoConfigComponent::group(const QString& name ) const { return mGroups.find( name ); } void QGpgMECryptoConfigComponent::sync( bool runtime ) { KTempFile tmpFile; tmpFile.setAutoDelete( true ); QValueList dirtyEntries; // Collect all dirty entries QDictIterator groupit( mGroups ); for( ; groupit.current(); ++groupit ) { QDictIterator it( groupit.current()->mEntries ); for( ; it.current(); ++it ) { if ( it.current()->isDirty() ) { // OK, we can set it.currentKey() to it.current()->outputString() QString line = it.currentKey(); if ( it.current()->isSet() ) { // set option line += ":0:"; line += it.current()->outputString(); } else { // unset option line += ":16:"; } line += '\n'; QCString line8bit = line.utf8(); // encode with utf8, and KProcIO uses utf8 when reading. tmpFile.file()->writeBlock( line8bit.data(), line8bit.size()-1 /*no 0*/ ); dirtyEntries.append( it.current() ); } } } tmpFile.close(); if ( dirtyEntries.isEmpty() ) return; // Call gpgconf --change-options QString commandLine = "gpgconf"; if ( runtime ) commandLine += " --runtime"; commandLine += " --change-options "; commandLine += KProcess::quote( mName ); commandLine += " < "; commandLine += KProcess::quote( tmpFile.name() ); //kdDebug(5150) << commandLine << endl; //system( QCString( "cat " ) + tmpFile.name().latin1() ); // DEBUG KProcess proc; proc.setUseShell( true ); proc << commandLine; // run the process: int rc = 0; if ( !proc.start( KProcess::Block ) ) rc = -1; else rc = ( proc.normalExit() ) ? proc.exitStatus() : -1 ; if ( rc == -1 ) { QString wmsg = i18n( "Could not start gpgconf\nCheck that gpgconf is in the PATH and that it can be started" ); kdWarning(5150) << wmsg << endl; KMessageBox::error(0, wmsg); } else if( rc != 0 ) // Happens due to bugs in gpgconf (e.g. issues 104/115) { QString wmsg = i18n( "Error from gpgconf while saving configuration: %1" ).arg( strerror( rc ) ); kdWarning(5150) << k_funcinfo << ":" << strerror( rc ) << endl; KMessageBox::error(0, wmsg); } else { QValueList::Iterator it = dirtyEntries.begin(); for( ; it != dirtyEntries.end(); ++it ) { (*it)->setDirty( false ); } } } //// QGpgMECryptoConfigGroup::QGpgMECryptoConfigGroup( const QString & name, const QString& description, int level ) : mEntries( 29 ), mName( name ), mDescription( description ), mLevel( static_cast( level ) ) { mEntries.setAutoDelete( true ); } QStringList QGpgMECryptoConfigGroup::entryList() const { QDictIterator it( mEntries ); QStringList names; for( ; it.current(); ++it ) names.push_back( it.currentKey() ); return names; } Kleo::CryptoConfigEntry* QGpgMECryptoConfigGroup::entry( const QString& name ) const { return mEntries.find( name ); } //// static QString gpgconf_unescape( const QString& str ) { // Looks like it's the same rules as KURL. return KURL::decode_string( str, 106 ); } static QString gpgconf_escape( const QString& str ) { // Escape special chars (including ':' and '%') QString enc = KURL::encode_string( str, 106 ); // and convert to utf8 first (to get %12%34 for one special char) // Also encode commas, for lists. enc.replace( ',', "%2c" ); return enc; } static QString urlpart_encode( const QString& str ) { QString enc( str ); enc.replace( '%', "%25" ); // first! enc.replace( ':', "%3a" ); //kdDebug() << " urlpart_encode: " << str << " -> " << enc << endl; return enc; } static QString urlpart_decode( const QString& str ) { return KURL::decode_string( str ); } // gpgconf arg type number -> CryptoConfigEntry arg type enum mapping static Kleo::CryptoConfigEntry::ArgType knownArgType( int argType, bool& ok ) { ok = true; switch( argType ) { case 0: // none return Kleo::CryptoConfigEntry::ArgType_None; case 1: // string return Kleo::CryptoConfigEntry::ArgType_String; case 2: // int32 return Kleo::CryptoConfigEntry::ArgType_Int; case 3: // uint32 return Kleo::CryptoConfigEntry::ArgType_UInt; case 32: // pathname return Kleo::CryptoConfigEntry::ArgType_Path; case 33: // ldap server return Kleo::CryptoConfigEntry::ArgType_LDAPURL; default: ok = false; return Kleo::CryptoConfigEntry::ArgType_None; } } QGpgMECryptoConfigEntry::QGpgMECryptoConfigEntry( const QStringList& parsedLine ) { // Format: NAME:FLAGS:LEVEL:DESCRIPTION:TYPE:ALT-TYPE:ARGNAME:DEFAULT:ARGDEF:VALUE assert( parsedLine.count() >= 10 ); // called checked for it already QStringList::const_iterator it = parsedLine.begin(); mName = *it++; mFlags = (*it++).toInt(); mLevel = (*it++).toInt(); mDescription = *it++; bool ok; // we keep the real (int) arg type, since it influences the parsing (e.g. for ldap urls) mRealArgType = (*it++).toInt(); mArgType = knownArgType( mRealArgType, ok ); if ( !ok && !(*it).isEmpty() ) { // use ALT-TYPE mRealArgType = (*it).toInt(); mArgType = knownArgType( mRealArgType, ok ); } if ( !ok ) kdWarning(5150) << "Unsupported datatype: " << parsedLine[4] << " : " << *it << " for " << parsedLine[0] << endl; ++it; // done with alt-type ++it; // skip argname (not useful in GUIs) mSet = false; QString value; if ( mFlags & GPGCONF_FLAG_DEFAULT ) { value = *it; // get default value mDefaultValue = stringToValue( value, true ); } ++it; // done with DEFAULT ++it; // ### skip ARGDEF for now. It's only for options with an "optional arg" //kdDebug(5150) << "Entry " << parsedLine[0] << " val=" << *it << endl; if ( !(*it).isEmpty() ) { // a real value was set mSet = true; value = *it; mValue = stringToValue( value, true ); } else { mValue = mDefaultValue; } mDirty = false; } QVariant QGpgMECryptoConfigEntry::stringToValue( const QString& str, bool unescape ) const { bool isString = isStringType(); if ( isList() ) { QValueList lst; QStringList items = QStringList::split( ',', str ); for( QStringList::const_iterator valit = items.begin(); valit != items.end(); ++valit ) { QString val = *valit; if ( isString ) { if ( val.isEmpty() ) { lst << QString::null; continue; } else if ( unescape ) { if( val[0] != '"' ) // see README.gpgconf kdWarning(5150) << "String value should start with '\"' : " << val << endl; val = val.mid( 1 ); } } lst << QVariant( unescape ? gpgconf_unescape( val ) : val ); } return lst; } else { // not a list QString val( str ); if ( isString ) { if ( val.isEmpty() ) return QVariant( QString::null ); // not set [ok with lists too?] else if ( unescape ) { Q_ASSERT( val[0] == '"' ); // see README.gpgconf val = val.mid( 1 ); } } return QVariant( unescape ? gpgconf_unescape( val ) : val ); } } QGpgMECryptoConfigEntry::~QGpgMECryptoConfigEntry() { #ifndef NDEBUG if ( !s_duringClear && mDirty ) kdWarning(5150) << "Deleting a QGpgMECryptoConfigEntry that was modified (" << mDescription << ")\n" << "You forgot to call sync() (to commit) or clear() (to discard)" << endl; #endif } bool QGpgMECryptoConfigEntry::isOptional() const { return mFlags & GPGCONF_FLAG_OPTIONAL; } bool QGpgMECryptoConfigEntry::isList() const { return mFlags & GPGCONF_FLAG_LIST; } bool QGpgMECryptoConfigEntry::isRuntime() const { return mFlags & GPGCONF_FLAG_RUNTIME; } bool QGpgMECryptoConfigEntry::isSet() const { return mSet; } bool QGpgMECryptoConfigEntry::boolValue() const { Q_ASSERT( mArgType == ArgType_None ); Q_ASSERT( !isList() ); return mValue.toBool(); } QString QGpgMECryptoConfigEntry::stringValue() const { return toString( false ); } int QGpgMECryptoConfigEntry::intValue() const { Q_ASSERT( mArgType == ArgType_Int ); Q_ASSERT( !isList() ); return mValue.toInt(); } unsigned int QGpgMECryptoConfigEntry::uintValue() const { Q_ASSERT( mArgType == ArgType_UInt ); Q_ASSERT( !isList() ); return mValue.toUInt(); } static KURL parseURL( int mRealArgType, const QString& str ) { if ( mRealArgType == 33 ) { // LDAP server // The format is HOSTNAME:PORT:USERNAME:PASSWORD:BASE_DN QStringList items = QStringList::split( ':', str, true ); if ( items.count() == 5 ) { QStringList::const_iterator it = items.begin(); KURL url; url.setProtocol( "ldap" ); url.setHost( urlpart_decode( *it++ ) ); url.setPort( (*it++).toInt() ); url.setPath( "/" ); // workaround KURL parsing bug url.setUser( urlpart_decode( *it++ ) ); url.setPass( urlpart_decode( *it++ ) ); url.setQuery( urlpart_decode( *it ) ); return url; } else kdWarning(5150) << "parseURL: malformed LDAP server: " << str << endl; } // other URLs : assume wellformed URL syntax. return KURL( str ); } // The opposite of parseURL static QString splitURL( int mRealArgType, const KURL& url ) { if ( mRealArgType == 33 ) { // LDAP server // The format is HOSTNAME:PORT:USERNAME:PASSWORD:BASE_DN Q_ASSERT( url.protocol() == "ldap" ); return urlpart_encode( url.host() ) + ":" + QString::number( url.port() ) + ":" + urlpart_encode( url.user() ) + ":" + urlpart_encode( url.pass() ) + ":" + // KURL automatically encoded the query (e.g. for spaces inside it), // so decode it before writing it out to gpgconf (issue119) urlpart_encode( KURL::decode_string( url.query().mid(1) ) ); } return url.path(); } KURL QGpgMECryptoConfigEntry::urlValue() const { Q_ASSERT( mArgType == ArgType_Path || mArgType == ArgType_URL || mArgType == ArgType_LDAPURL ); Q_ASSERT( !isList() ); QString str = mValue.toString(); if ( mArgType == ArgType_Path ) { KURL url; url.setPath( str ); return url; } return parseURL( mRealArgType, str ); } unsigned int QGpgMECryptoConfigEntry::numberOfTimesSet() const { Q_ASSERT( mArgType == ArgType_None ); Q_ASSERT( isList() ); return mValue.toUInt(); } QStringList QGpgMECryptoConfigEntry::stringValueList() const { Q_ASSERT( isStringType() ); Q_ASSERT( isList() ); return mValue.toStringList(); } QValueList QGpgMECryptoConfigEntry::intValueList() const { Q_ASSERT( mArgType == ArgType_Int ); Q_ASSERT( isList() ); QValueList ret; QValueList lst = mValue.toList(); for( QValueList::const_iterator it = lst.begin(); it != lst.end(); ++it ) { ret.append( (*it).toInt() ); } return ret; } QValueList QGpgMECryptoConfigEntry::uintValueList() const { Q_ASSERT( mArgType == ArgType_UInt ); Q_ASSERT( isList() ); QValueList ret; QValueList lst = mValue.toList(); for( QValueList::const_iterator it = lst.begin(); it != lst.end(); ++it ) { ret.append( (*it).toUInt() ); } return ret; } KURL::List QGpgMECryptoConfigEntry::urlValueList() const { Q_ASSERT( mArgType == ArgType_Path || mArgType == ArgType_URL || mArgType == ArgType_LDAPURL ); Q_ASSERT( isList() ); QStringList lst = mValue.toStringList(); KURL::List ret; for( QStringList::const_iterator it = lst.begin(); it != lst.end(); ++it ) { if ( mArgType == ArgType_Path ) { KURL url; url.setPath( *it ); ret << url; } else { ret << parseURL( mRealArgType, *it ); } } return ret; } void QGpgMECryptoConfigEntry::resetToDefault() { mSet = false; mDirty = true; if ( mFlags & GPGCONF_FLAG_DEFAULT ) mValue = mDefaultValue; else if ( mArgType == ArgType_None ) mValue = false; } void QGpgMECryptoConfigEntry::setBoolValue( bool b ) { Q_ASSERT( mArgType == ArgType_None ); Q_ASSERT( !isList() ); // A "no arg" option is either set or not set. // Being set means mSet==true + mValue==true, being unset means resetToDefault(), i.e. both false mValue = b; mSet = b; mDirty = true; } void QGpgMECryptoConfigEntry::setStringValue( const QString& str ) { mValue = stringToValue( str, false ); // When setting a string to empty (and there's no default), we need to act like resetToDefault // Otherwise we try e.g. "ocsp-responder:0:" and gpgconf answers: // "gpgconf: argument required for option ocsp-responder" if ( str.isEmpty() && !isOptional() ) mSet = false; else mSet = true; mDirty = true; } void QGpgMECryptoConfigEntry::setIntValue( int i ) { Q_ASSERT( mArgType == ArgType_Int ); Q_ASSERT( !isList() ); mValue = i; mSet = true; mDirty = true; } void QGpgMECryptoConfigEntry::setUIntValue( unsigned int i ) { mValue = i; mSet = true; mDirty = true; } void QGpgMECryptoConfigEntry::setURLValue( const KURL& url ) { QString str = splitURL( mRealArgType, url ); if ( str.isEmpty() && !isOptional() ) mSet = false; else mSet = true; mValue = str; mDirty = true; } void QGpgMECryptoConfigEntry::setNumberOfTimesSet( unsigned int i ) { Q_ASSERT( mArgType == ArgType_None ); Q_ASSERT( isList() ); setUIntValue( i ); } void QGpgMECryptoConfigEntry::setStringValueList( const QStringList& lst ) { mValue = lst; if ( lst.isEmpty() && !isOptional() ) mSet = false; else mSet = true; mDirty = true; } void QGpgMECryptoConfigEntry::setIntValueList( const QValueList& lst ) { QValueList ret; for( QValueList::const_iterator it = lst.begin(); it != lst.end(); ++it ) { ret << QVariant( *it ); } mValue = ret; if ( ret.isEmpty() && !isOptional() ) mSet = false; else mSet = true; mDirty = true; } void QGpgMECryptoConfigEntry::setUIntValueList( const QValueList& lst ) { QValueList ret; for( QValueList::const_iterator it = lst.begin(); it != lst.end(); ++it ) { ret << QVariant( *it ); } if ( ret.isEmpty() && !isOptional() ) mSet = false; else mSet = true; mValue = ret; mDirty = true; } void QGpgMECryptoConfigEntry::setURLValueList( const KURL::List& urls ) { QStringList lst; for( KURL::List::const_iterator it = urls.begin(); it != urls.end(); ++it ) { lst << splitURL( mRealArgType, *it ); } mValue = lst; if ( lst.isEmpty() && !isOptional() ) mSet = false; else mSet = true; mDirty = true; } QString QGpgMECryptoConfigEntry::toString( bool escape ) const { // Basically the opposite of stringToValue if ( isStringType() ) { if ( mValue.isNull() ) return QString::null; else if ( isList() ) { // string list QStringList lst = mValue.toStringList(); if ( escape ) { for( QStringList::iterator it = lst.begin(); it != lst.end(); ++it ) { if ( !(*it).isNull() ) *it = gpgconf_escape( *it ).prepend( "\"" ); } } QString res = lst.join( "," ); kdDebug(5150) << "toString: " << res << endl; return res; } else { // normal string QString res = mValue.toString(); if ( escape ) res = gpgconf_escape( res ).prepend( "\"" ); return res; } } if ( !isList() ) // non-list non-string { if ( mArgType == ArgType_None ) { return mValue.toBool() ? QString::fromLatin1( "1" ) : QString::null; } else { // some int Q_ASSERT( mArgType == ArgType_Int || mArgType == ArgType_UInt ); return mValue.toString(); // int to string conversion } } // Lists (of other types than strings) if ( mArgType == ArgType_None ) return QString::number( numberOfTimesSet() ); QStringList ret; QValueList lst = mValue.toList(); for( QValueList::const_iterator it = lst.begin(); it != lst.end(); ++it ) { ret << (*it).toString(); // QVariant does the conversion } return ret.join( "," ); } QString QGpgMECryptoConfigEntry::outputString() const { Q_ASSERT( mSet ); return toString( true ); } bool QGpgMECryptoConfigEntry::isStringType() const { return ( mArgType == Kleo::CryptoConfigEntry::ArgType_String || mArgType == Kleo::CryptoConfigEntry::ArgType_Path || mArgType == Kleo::CryptoConfigEntry::ArgType_URL || mArgType == Kleo::CryptoConfigEntry::ArgType_LDAPURL ); } void QGpgMECryptoConfigEntry::setDirty( bool b ) { mDirty = b; } #include "qgpgmecryptoconfig.moc" diff --git a/lib/backends/qgpgme/qgpgmecryptoconfig.h b/lib/backends/qgpgme/qgpgmecryptoconfig.h index 8e8ae5988..cc3de2a2d 100644 --- a/lib/backends/qgpgme/qgpgmecryptoconfig.h +++ b/lib/backends/qgpgme/qgpgmecryptoconfig.h @@ -1,185 +1,185 @@ /* qgpgmecryptoconfig.h This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifndef KLEO_QGPGMECRYPTOCONFIG_H #define KLEO_QGPGMECRYPTOCONFIG_H #include #include #include #include #include class KProcIO; class QGpgMECryptoConfigComponent; class QGpgMECryptoConfigEntry; /** * CryptoConfig implementation around the gpgconf command-line tool * For method docu, see kleo/cryptoconfig.h */ class QGpgMECryptoConfig : public QObject, public Kleo::CryptoConfig { Q_OBJECT public: /** * Constructor */ QGpgMECryptoConfig(); virtual ~QGpgMECryptoConfig(); virtual QStringList componentList() const; virtual Kleo::CryptoConfigComponent* component( const QString& name ) const; virtual void clear(); virtual void sync( bool runtime ); private slots: void slotCollectStdOut( KProcIO* proc ); private: /// @param showErrors if true, a messagebox will be shown if e.g. gpgconf wasn't found void runGpgConf( bool showErrors ); private: QDict mComponents; bool mParsed; }; class QGpgMECryptoConfigGroup; /// For docu, see kleo/cryptoconfig.h class QGpgMECryptoConfigComponent : public QObject, public Kleo::CryptoConfigComponent { Q_OBJECT public: QGpgMECryptoConfigComponent( QGpgMECryptoConfig*, const QString& name, const QString& description ); ~QGpgMECryptoConfigComponent(); QString name() const { return mName; } QString iconName() const { return mName; } QString description() const { return mDescription; } QStringList groupList() const; Kleo::CryptoConfigGroup* group( const QString& name ) const; void sync( bool runtime ); private slots: void slotCollectStdOut( KProcIO* proc ); private: void runGpgConf(); private: QDict mGroups; QString mName; QString mDescription; QGpgMECryptoConfigGroup* mCurrentGroup; // during parsing QString mCurrentGroupName; // during parsing }; class QGpgMECryptoConfigGroup : public Kleo::CryptoConfigGroup { public: QGpgMECryptoConfigGroup( const QString & name, const QString& description, int level ); ~QGpgMECryptoConfigGroup() {} QString name() const { return mName; } QString iconName() const { return QString::null; } QString description() const { return mDescription; } Kleo::CryptoConfigEntry::Level level() const { return mLevel; } QStringList entryList() const; Kleo::CryptoConfigEntry* entry( const QString& name ) const; private: friend class QGpgMECryptoConfigComponent; // it adds the entries QDict mEntries; QString mName; QString mDescription; Kleo::CryptoConfigEntry::Level mLevel; }; class QGpgMECryptoConfigEntry : public Kleo::CryptoConfigEntry { public: QGpgMECryptoConfigEntry( const QStringList& parsedLine ); ~QGpgMECryptoConfigEntry(); QString name() const { return mName; } QString description() const { return mDescription; } bool isOptional() const; bool isList() const; bool isRuntime() const; Level level() const { return static_cast( mLevel ); } ArgType argType() const { return static_cast( mArgType ); } bool isSet() const; bool boolValue() const; QString stringValue() const; int intValue() const; unsigned int uintValue() const; KURL urlValue() const; unsigned int numberOfTimesSet() const; QStringList stringValueList() const; QValueList intValueList() const; QValueList uintValueList() const; KURL::List urlValueList() const; void resetToDefault(); void setBoolValue( bool ); void setStringValue( const QString& ); void setIntValue( int ); void setUIntValue( unsigned int ); void setURLValue( const KURL& ); void setNumberOfTimesSet( unsigned int ); void setStringValueList( const QStringList& ); void setIntValueList( const QValueList& ); void setUIntValueList( const QValueList& ); void setURLValueList( const KURL::List& ); bool isDirty() const { return mDirty; } void setDirty( bool b ); QString outputString() const; protected: bool isStringType() const; QVariant stringToValue( const QString& value, bool unescape ) const; QString toString( bool escape ) const; private: QString mName; QString mDescription; QVariant mDefaultValue; QVariant mValue; uint mFlags : 7; // bitfield with 7 bits uint mLevel : 3; // max is 4 (2, in fact) -> 3 bits uint mRealArgType : 6; // max is 33 -> 6 bits uint mArgType : 3; // max is 6 (ArgType enum) -> 3 bits; uint mDirty : 1; uint mSet : 1; }; #endif /* KLEO_QGPGMECRYPTOCONFIG_H */ diff --git a/lib/backends/qgpgme/qgpgmedecryptjob.cpp b/lib/backends/qgpgme/qgpgmedecryptjob.cpp new file mode 100644 index 000000000..884f1a4a0 --- /dev/null +++ b/lib/backends/qgpgme/qgpgmedecryptjob.cpp @@ -0,0 +1,90 @@ +/* + qgpgmedecryptjob.cpp + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "qgpgmedecryptjob.h" + +#include +#include + +#include +#include +#include + +#include + +Kleo::QGpgMEDecryptJob::QGpgMEDecryptJob( GpgME::Context * context ) + : DecryptJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMEDecryptJob" ), + QGpgMEJob( this, context ) +{ + assert( context ); +} + +Kleo::QGpgMEDecryptJob::~QGpgMEDecryptJob() { +} + +void Kleo::QGpgMEDecryptJob::setup( const QByteArray & cipherText ) { + assert( !mInData ); + assert( !mOutData ); + + createInData( cipherText ); + createOutData(); +} + +GpgME::Error Kleo::QGpgMEDecryptJob::start( const QByteArray & cipherText ) { + setup( cipherText ); + + hookupContextToEventLoopInteractor(); + + const GpgME::Error err = mCtx->startDecryption( *mInData, *mOutData ); + + if ( err ) + deleteLater(); + return err; +} + +GpgME::DecryptionResult Kleo::QGpgMEDecryptJob::exec( const QByteArray & cipherText, + QByteArray & plainText ) { + setup( cipherText ); + const GpgME::DecryptionResult result = mCtx->decrypt( *mInData, *mOutData ); + plainText = mOutDataDataProvider->data(); + return result; +} + +void Kleo::QGpgMEDecryptJob::doOperationDoneEvent( const GpgME::Error & ) { + emit result( mCtx->decryptionResult(), mOutDataDataProvider->data() ); +} + +#include "qgpgmedecryptjob.moc" diff --git a/lib/backends/chiasmus/chiasmuslibrary.h b/lib/backends/qgpgme/qgpgmedecryptjob.h similarity index 57% copy from lib/backends/chiasmus/chiasmuslibrary.h copy to lib/backends/qgpgme/qgpgmedecryptjob.h index 1759b4fc7..7fc89dff2 100644 --- a/lib/backends/chiasmus/chiasmuslibrary.h +++ b/lib/backends/qgpgme/qgpgmedecryptjob.h @@ -1,68 +1,74 @@ -/* -*- mode: C++; c-file-style: "gnu" -*- - chiasmuslibrary.h +/* + qgpgmedecryptjob.h This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ +#ifndef __KLEO_QGPGMEDECRYPTJOB_H__ +#define __KLEO_QGPGMEDECRYPTJOB_H__ -#ifndef __KLEO_CHIASMUSLIBRARY_H__ -#define __KLEO_CHIASMUSLIBRARY_H__ +#include + +#include "qgpgmejob.h" -#include #include -class KLibrary; +namespace GpgME { + class Error; + class Context; +} namespace Kleo { - /** - @short small helper class to load xia.o through xia.so and make - the functionality available. - */ - class ChiasmusLibrary { - ChiasmusLibrary(); - ~ChiasmusLibrary(); + class QGpgMEDecryptJob : public DecryptJob, private QGpgMEJob { + Q_OBJECT QGPGME_JOB public: - static const ChiasmusLibrary * instance(); - static void deleteInstance(); + QGpgMEDecryptJob( GpgME::Context * context ); + ~QGpgMEDecryptJob(); - int perform( const QValueVector & args ) const; - private: - typedef int ( *main_func )( int, char** ); - main_func chiasmus( QString * reason=0 ) const; + /*! \reimp from DecryptJob */ + GpgME::Error start( const QByteArray & cipherText ); + + /*! \reimp from DecryptJob */ + GpgME::DecryptionResult exec( const QByteArray & cipherText, + QByteArray & plainText ); + + private slots: + void slotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e ) { + QGpgMEJob::doSlotOperationDoneEvent( context, e ); + } private: - static ChiasmusLibrary * self; - mutable KLibrary * mXiaLibrary; + void doOperationDoneEvent( const GpgME::Error & e ); + void setup( const QByteArray & cipherText ); }; } - -#endif // __KLEO_CHIASMUSLIBRARY_H__ +#endif // __KLEO_QGPGMEDECRYPTJOB_H__ diff --git a/lib/backends/qgpgme/qgpgmedecryptverifyjob.cpp b/lib/backends/qgpgme/qgpgmedecryptverifyjob.cpp new file mode 100644 index 000000000..509327aa8 --- /dev/null +++ b/lib/backends/qgpgme/qgpgmedecryptverifyjob.cpp @@ -0,0 +1,94 @@ +/* + qgpgmedecryptverifyjob.cpp + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "qgpgmedecryptverifyjob.h" + +#include +#include + +#include +#include +#include +#include + +#include + +Kleo::QGpgMEDecryptVerifyJob::QGpgMEDecryptVerifyJob( GpgME::Context * context ) + : DecryptVerifyJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMEDecryptVerifyJob" ), + QGpgMEJob( this, context ) +{ + assert( context ); +} + +Kleo::QGpgMEDecryptVerifyJob::~QGpgMEDecryptVerifyJob() { +} + +void Kleo::QGpgMEDecryptVerifyJob::setup( const QByteArray & cipherText ) { + assert( !mInData ); + assert( !mOutData ); + + createInData( cipherText ); + createOutData(); +} + +GpgME::Error Kleo::QGpgMEDecryptVerifyJob::start( const QByteArray & cipherText ) { + setup( cipherText ); + + hookupContextToEventLoopInteractor(); + + const GpgME::Error err = mCtx->startCombinedDecryptionAndVerification( *mInData, *mOutData ); + + if ( err ) + deleteLater(); + return err; +} + +std::pair +Kleo::QGpgMEDecryptVerifyJob::exec( const QByteArray & cipherText, QByteArray & plainText ) { + setup( cipherText ); + const std::pair result = + mCtx->decryptAndVerify( *mInData, *mOutData ); + plainText = mOutDataDataProvider->data(); + return result; +} + +void Kleo::QGpgMEDecryptVerifyJob::doOperationDoneEvent( const GpgME::Error & ) { + emit result( mCtx->decryptionResult(), + mCtx->verificationResult(), + mOutDataDataProvider->data() ); +} + +#include "qgpgmedecryptverifyjob.moc" diff --git a/lib/backends/chiasmus/chiasmuslibrary.h b/lib/backends/qgpgme/qgpgmedecryptverifyjob.h similarity index 55% copy from lib/backends/chiasmus/chiasmuslibrary.h copy to lib/backends/qgpgme/qgpgmedecryptverifyjob.h index 1759b4fc7..a39188746 100644 --- a/lib/backends/chiasmus/chiasmuslibrary.h +++ b/lib/backends/qgpgme/qgpgmedecryptverifyjob.h @@ -1,68 +1,75 @@ -/* -*- mode: C++; c-file-style: "gnu" -*- - chiasmuslibrary.h +/* + qgpgmedecryptverifyjob.h This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ +#ifndef __KLEO_QGPGMEDECRYPTVERIFYJOB_H__ +#define __KLEO_QGPGMEDECRYPTVERIFYJOB_H__ -#ifndef __KLEO_CHIASMUSLIBRARY_H__ -#define __KLEO_CHIASMUSLIBRARY_H__ +#include + +#include "qgpgmejob.h" -#include #include +#include -class KLibrary; +namespace GpgME { + class Error; + class Context; +} namespace Kleo { - /** - @short small helper class to load xia.o through xia.so and make - the functionality available. - */ - class ChiasmusLibrary { - ChiasmusLibrary(); - ~ChiasmusLibrary(); + class KDE_EXPORT QGpgMEDecryptVerifyJob : public DecryptVerifyJob, private QGpgMEJob { + Q_OBJECT QGPGME_JOB public: - static const ChiasmusLibrary * instance(); - static void deleteInstance(); + QGpgMEDecryptVerifyJob( GpgME::Context * context ); + ~QGpgMEDecryptVerifyJob(); - int perform( const QValueVector & args ) const; - private: - typedef int ( *main_func )( int, char** ); - main_func chiasmus( QString * reason=0 ) const; + /*! \reimp from DecryptVerifyJob */ + GpgME::Error start( const QByteArray & cipherText ); + + /*! \reimp from DecryptVerifyJob */ + std::pair + exec( const QByteArray & cipherText, QByteArray & plainText ); + + private slots: + void slotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e ) { + QGpgMEJob::doSlotOperationDoneEvent( context, e ); + } private: - static ChiasmusLibrary * self; - mutable KLibrary * mXiaLibrary; + void doOperationDoneEvent( const GpgME::Error & e ); + void setup( const QByteArray & ); }; } - -#endif // __KLEO_CHIASMUSLIBRARY_H__ +#endif // __KLEO_QGPGMEDECRYPTVERIFYJOB_H__ diff --git a/lib/backends/chiasmus/chiasmuslibrary.h b/lib/backends/qgpgme/qgpgmedeletejob.cpp similarity index 57% copy from lib/backends/chiasmus/chiasmuslibrary.h copy to lib/backends/qgpgme/qgpgmedeletejob.cpp index 1759b4fc7..c06907eea 100644 --- a/lib/backends/chiasmus/chiasmuslibrary.h +++ b/lib/backends/qgpgme/qgpgmedeletejob.cpp @@ -1,68 +1,70 @@ -/* -*- mode: C++; c-file-style: "gnu" -*- - chiasmuslibrary.h +/* + qgpgmedeletejob.cpp This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ +#ifdef HAVE_CONFIG_H +#include +#endif -#ifndef __KLEO_CHIASMUSLIBRARY_H__ -#define __KLEO_CHIASMUSLIBRARY_H__ +#include "qgpgmedeletejob.h" -#include -#include +#include -class KLibrary; +#include -namespace Kleo { +#include - /** - @short small helper class to load xia.o through xia.so and make - the functionality available. - */ - class ChiasmusLibrary { - ChiasmusLibrary(); - ~ChiasmusLibrary(); - public: - static const ChiasmusLibrary * instance(); - static void deleteInstance(); +Kleo::QGpgMEDeleteJob::QGpgMEDeleteJob( GpgME::Context * context ) + : DeleteJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMEDeleteJob" ), + QGpgMEJob( this, context ) +{ + assert( context ); +} + +Kleo::QGpgMEDeleteJob::~QGpgMEDeleteJob() { +} - int perform( const QValueVector & args ) const; - private: - typedef int ( *main_func )( int, char** ); - main_func chiasmus( QString * reason=0 ) const; +GpgME::Error Kleo::QGpgMEDeleteJob::start( const GpgME::Key & key, bool allowSecretKeyDeletion ) { - private: - static ChiasmusLibrary * self; - mutable KLibrary * mXiaLibrary; - }; + hookupContextToEventLoopInteractor(); + const GpgME::Error err = mCtx->startKeyDeletion( key, allowSecretKeyDeletion ); + + if ( err ) + deleteLater(); + return err; } +void Kleo::QGpgMEDeleteJob::doOperationDoneEvent( const GpgME::Error & error ) { + emit result( error ); +} -#endif // __KLEO_CHIASMUSLIBRARY_H__ +#include "qgpgmedeletejob.moc" diff --git a/lib/backends/chiasmus/chiasmuslibrary.h b/lib/backends/qgpgme/qgpgmedeletejob.h similarity index 61% copy from lib/backends/chiasmus/chiasmuslibrary.h copy to lib/backends/qgpgme/qgpgmedeletejob.h index 1759b4fc7..9dec128f7 100644 --- a/lib/backends/chiasmus/chiasmuslibrary.h +++ b/lib/backends/qgpgme/qgpgmedeletejob.h @@ -1,68 +1,68 @@ -/* -*- mode: C++; c-file-style: "gnu" -*- - chiasmuslibrary.h +/* + qgpgmedeletejob.h This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ +#ifndef __KLEO_QGPGMEDELETEJOB_H__ +#define __KLEO_QGPGMEDELETEJOB_H__ -#ifndef __KLEO_CHIASMUSLIBRARY_H__ -#define __KLEO_CHIASMUSLIBRARY_H__ +#include -#include -#include +#include "qgpgmejob.h" -class KLibrary; +namespace GpgME { + class Error; + class Context; + class Key; +} namespace Kleo { - /** - @short small helper class to load xia.o through xia.so and make - the functionality available. - */ - class ChiasmusLibrary { - ChiasmusLibrary(); - ~ChiasmusLibrary(); + class QGpgMEDeleteJob : public DeleteJob, private QGpgMEJob { + Q_OBJECT QGPGME_JOB public: - static const ChiasmusLibrary * instance(); - static void deleteInstance(); + QGpgMEDeleteJob( GpgME::Context * context ); + ~QGpgMEDeleteJob(); - int perform( const QValueVector & args ) const; - private: - typedef int ( *main_func )( int, char** ); - main_func chiasmus( QString * reason=0 ) const; + /*! \reimp from DeleteJob */ + GpgME::Error start( const GpgME::Key & key, bool allowSecretKeyDeletion ); + + private slots: + void slotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e ) { + QGpgMEJob::doSlotOperationDoneEvent( context, e ); + } private: - static ChiasmusLibrary * self; - mutable KLibrary * mXiaLibrary; + void doOperationDoneEvent( const GpgME::Error & e ); }; } - -#endif // __KLEO_CHIASMUSLIBRARY_H__ +#endif // __KLEO_QGPGMEDELETEJOB_H__ diff --git a/lib/backends/chiasmus/chiasmuslibrary.h b/lib/backends/qgpgme/qgpgmedownloadjob.cpp similarity index 53% copy from lib/backends/chiasmus/chiasmuslibrary.h copy to lib/backends/qgpgme/qgpgmedownloadjob.cpp index 1759b4fc7..6ee771a04 100644 --- a/lib/backends/chiasmus/chiasmuslibrary.h +++ b/lib/backends/qgpgme/qgpgmedownloadjob.cpp @@ -1,68 +1,78 @@ -/* -*- mode: C++; c-file-style: "gnu" -*- - chiasmuslibrary.h +/* + qgpgmedownloadjob.cpp This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ +#ifdef HAVE_CONFIG_H +#include +#endif -#ifndef __KLEO_CHIASMUSLIBRARY_H__ -#define __KLEO_CHIASMUSLIBRARY_H__ +#include "qgpgmedownloadjob.h" -#include -#include +#include +#include -class KLibrary; +#include +#include -namespace Kleo { +#include - /** - @short small helper class to load xia.o through xia.so and make - the functionality available. - */ - class ChiasmusLibrary { - ChiasmusLibrary(); - ~ChiasmusLibrary(); - public: - static const ChiasmusLibrary * instance(); - static void deleteInstance(); +#include - int perform( const QValueVector & args ) const; - private: - typedef int ( *main_func )( int, char** ); - main_func chiasmus( QString * reason=0 ) const; +Kleo::QGpgMEDownloadJob::QGpgMEDownloadJob( GpgME::Context * context ) + : DownloadJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMEDownloadJob" ), + QGpgMEJob( this, context ) +{ + assert( context ); +} + +Kleo::QGpgMEDownloadJob::~QGpgMEDownloadJob() { +} - private: - static ChiasmusLibrary * self; - mutable KLibrary * mXiaLibrary; - }; +GpgME::Error Kleo::QGpgMEDownloadJob::start( const QStringList & pats ) { + assert( !patterns() ); + assert( !mOutData ); + createOutData(); + setPatterns( pats ); + hookupContextToEventLoopInteractor(); + + const GpgME::Error err = mCtx->startPublicKeyExport( patterns(), *mOutData ); + + if ( err ) + deleteLater(); + return err; } +void Kleo::QGpgMEDownloadJob::doOperationDoneEvent( const GpgME::Error & error ) { + emit result( error, mOutDataDataProvider->data() ); +} -#endif // __KLEO_CHIASMUSLIBRARY_H__ +#include "qgpgmedownloadjob.moc" diff --git a/lib/backends/chiasmus/chiasmuslibrary.h b/lib/backends/qgpgme/qgpgmedownloadjob.h similarity index 61% copy from lib/backends/chiasmus/chiasmuslibrary.h copy to lib/backends/qgpgme/qgpgmedownloadjob.h index 1759b4fc7..1402b127c 100644 --- a/lib/backends/chiasmus/chiasmuslibrary.h +++ b/lib/backends/qgpgme/qgpgmedownloadjob.h @@ -1,68 +1,67 @@ -/* -*- mode: C++; c-file-style: "gnu" -*- - chiasmuslibrary.h +/* + qgpgmedownloadjob.h This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ +#ifndef __KLEO_QGPGMEDOWNLOADJOB_H__ +#define __KLEO_QGPGMEDOWNLOADJOB_H__ -#ifndef __KLEO_CHIASMUSLIBRARY_H__ -#define __KLEO_CHIASMUSLIBRARY_H__ +#include -#include -#include +#include "qgpgmejob.h" -class KLibrary; +namespace GpgME { + class Error; + class Context; +} namespace Kleo { - /** - @short small helper class to load xia.o through xia.so and make - the functionality available. - */ - class ChiasmusLibrary { - ChiasmusLibrary(); - ~ChiasmusLibrary(); + class QGpgMEDownloadJob : public DownloadJob, private QGpgMEJob { + Q_OBJECT QGPGME_JOB public: - static const ChiasmusLibrary * instance(); - static void deleteInstance(); + QGpgMEDownloadJob( GpgME::Context * context ); + ~QGpgMEDownloadJob(); - int perform( const QValueVector & args ) const; - private: - typedef int ( *main_func )( int, char** ); - main_func chiasmus( QString * reason=0 ) const; + /*! \reimp from DownloadJob */ + GpgME::Error start( const QStringList & fingerprints ); private: - static ChiasmusLibrary * self; - mutable KLibrary * mXiaLibrary; + void doOperationDoneEvent( const GpgME::Error & e ); + + private slots: + void slotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e ) { + QGpgMEJob::doSlotOperationDoneEvent( context, e ); + } }; } - -#endif // __KLEO_CHIASMUSLIBRARY_H__ +#endif // __KLEO_QGPGMEDOWNLOADJOB_H__ diff --git a/lib/backends/qgpgme/qgpgmeencryptjob.cpp b/lib/backends/qgpgme/qgpgmeencryptjob.cpp new file mode 100644 index 000000000..01ef6b445 --- /dev/null +++ b/lib/backends/qgpgme/qgpgmeencryptjob.cpp @@ -0,0 +1,108 @@ +/* + qgpgmeencryptjob.cpp + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "qgpgmeencryptjob.h" + +#include +#include + +#include +#include + +#include +#include +#include + +#include + +Kleo::QGpgMEEncryptJob::QGpgMEEncryptJob( GpgME::Context * context ) + : EncryptJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMEEncryptJob" ), + QGpgMEJob( this, context ) +{ + assert( context ); +} + +Kleo::QGpgMEEncryptJob::~QGpgMEEncryptJob() { +} + +void Kleo::QGpgMEEncryptJob::setup( const QByteArray & plainText ) { + assert( !mInData ); + assert( !mOutData ); + + createInData( plainText ); + createOutData(); +} + +GpgME::Error Kleo::QGpgMEEncryptJob::start( const std::vector & recipients, + const QByteArray & plainText, bool alwaysTrust ) { + setup( plainText ); + + hookupContextToEventLoopInteractor(); + + const GpgME::Context::EncryptionFlags flags = + alwaysTrust ? GpgME::Context::AlwaysTrust : GpgME::Context::None; + const GpgME::Error err = mCtx->startEncryption( recipients, *mInData, *mOutData, flags ); + + if ( err ) + deleteLater(); + return err; +} + +GpgME::EncryptionResult Kleo::QGpgMEEncryptJob::exec( const std::vector & recipients, + const QByteArray & plainText, + bool alwaysTrust, + QByteArray & ciphertext ) { + setup( plainText ); + const GpgME::Context::EncryptionFlags flags = + alwaysTrust ? GpgME::Context::AlwaysTrust : GpgME::Context::None; + mResult = mCtx->encrypt( recipients, *mInData, *mOutData, flags ); + ciphertext = mOutDataDataProvider->data(); + return mResult; +} + +void Kleo::QGpgMEEncryptJob::doOperationDoneEvent( const GpgME::Error & ) { + emit result( mResult, mOutDataDataProvider->data() ); +} + +void Kleo::QGpgMEEncryptJob::showErrorDialog( QWidget * parent, const QString & caption ) const { + if ( !mResult.error() || mResult.error().isCanceled() ) + return; + const QString msg = i18n("Encryption failed: %1") + .arg( QString::fromLocal8Bit( mResult.error().asString() ) ); + KMessageBox::error( parent, msg, caption ); +} + +#include "qgpgmeencryptjob.moc" diff --git a/lib/backends/chiasmus/chiasmuslibrary.h b/lib/backends/qgpgme/qgpgmeencryptjob.h similarity index 51% copy from lib/backends/chiasmus/chiasmuslibrary.h copy to lib/backends/qgpgme/qgpgmeencryptjob.h index 1759b4fc7..362fb4e06 100644 --- a/lib/backends/chiasmus/chiasmuslibrary.h +++ b/lib/backends/qgpgme/qgpgmeencryptjob.h @@ -1,68 +1,86 @@ -/* -*- mode: C++; c-file-style: "gnu" -*- - chiasmuslibrary.h +/* + qgpgmeencryptjob.h This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ +#ifndef __KLEO_QGPGMEENCRYPTJOB_H__ +#define __KLEO_QGPGMEENCRYPTJOB_H__ -#ifndef __KLEO_CHIASMUSLIBRARY_H__ -#define __KLEO_CHIASMUSLIBRARY_H__ +#include + +#include "qgpgmejob.h" + +#include -#include #include -class KLibrary; +namespace GpgME { + class Error; + class Context; + class Key; +} namespace Kleo { - /** - @short small helper class to load xia.o through xia.so and make - the functionality available. - */ - class ChiasmusLibrary { - ChiasmusLibrary(); - ~ChiasmusLibrary(); + class QGpgMEEncryptJob : public EncryptJob, private QGpgMEJob { + Q_OBJECT QGPGME_JOB public: - static const ChiasmusLibrary * instance(); - static void deleteInstance(); + QGpgMEEncryptJob( GpgME::Context * context ); + ~QGpgMEEncryptJob(); + + /*! \reimp from EncryptJob */ + GpgME::Error start( const std::vector & recipients, + const QByteArray & plainText, bool alwaysTrust ); + + /*! \reimp from EncryptJob */ + GpgME::EncryptionResult exec( const std::vector & recipients, + const QByteArray & plainText, bool alwaysTrust, + QByteArray & cipherText ); + + /*! \reimp from Job */ + void showErrorDialog( QWidget * parent, const QString & caption ) const; + + private slots: + void slotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e ) { + QGpgMEJob::doSlotOperationDoneEvent( context, e ); + } + - int perform( const QValueVector & args ) const; private: - typedef int ( *main_func )( int, char** ); - main_func chiasmus( QString * reason=0 ) const; + void doOperationDoneEvent( const GpgME::Error & e ); + void setup( const QByteArray & ); private: - static ChiasmusLibrary * self; - mutable KLibrary * mXiaLibrary; + GpgME::EncryptionResult mResult; }; } - -#endif // __KLEO_CHIASMUSLIBRARY_H__ +#endif // __KLEO_QGPGMEENCRYPTJOB_H__ diff --git a/lib/backends/chiasmus/chiasmuslibrary.h b/lib/backends/qgpgme/qgpgmeexportjob.cpp similarity index 53% copy from lib/backends/chiasmus/chiasmuslibrary.h copy to lib/backends/qgpgme/qgpgmeexportjob.cpp index 1759b4fc7..c9274f3b7 100644 --- a/lib/backends/chiasmus/chiasmuslibrary.h +++ b/lib/backends/qgpgme/qgpgmeexportjob.cpp @@ -1,68 +1,78 @@ -/* -*- mode: C++; c-file-style: "gnu" -*- - chiasmuslibrary.h +/* + qgpgmeexportjob.cpp This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ +#ifdef HAVE_CONFIG_H +#include +#endif -#ifndef __KLEO_CHIASMUSLIBRARY_H__ -#define __KLEO_CHIASMUSLIBRARY_H__ +#include "qgpgmeexportjob.h" -#include -#include +#include +#include -class KLibrary; +#include +#include -namespace Kleo { +#include - /** - @short small helper class to load xia.o through xia.so and make - the functionality available. - */ - class ChiasmusLibrary { - ChiasmusLibrary(); - ~ChiasmusLibrary(); - public: - static const ChiasmusLibrary * instance(); - static void deleteInstance(); +#include - int perform( const QValueVector & args ) const; - private: - typedef int ( *main_func )( int, char** ); - main_func chiasmus( QString * reason=0 ) const; +Kleo::QGpgMEExportJob::QGpgMEExportJob( GpgME::Context * context ) + : ExportJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMEExportJob" ), + QGpgMEJob( this, context ) +{ + assert( context ); +} + +Kleo::QGpgMEExportJob::~QGpgMEExportJob() { +} - private: - static ChiasmusLibrary * self; - mutable KLibrary * mXiaLibrary; - }; +GpgME::Error Kleo::QGpgMEExportJob::start( const QStringList & pats ) { + assert( !patterns() ); + assert( !mOutData ); + createOutData(); + setPatterns( pats ); + hookupContextToEventLoopInteractor(); + + const GpgME::Error err = mCtx->startPublicKeyExport( patterns(), *mOutData ); + + if ( err ) + deleteLater(); + return err; } +void Kleo::QGpgMEExportJob::doOperationDoneEvent( const GpgME::Error & error ) { + emit result( error, mOutDataDataProvider->data() ); +} -#endif // __KLEO_CHIASMUSLIBRARY_H__ +#include "qgpgmeexportjob.moc" diff --git a/lib/backends/chiasmus/chiasmuslibrary.h b/lib/backends/qgpgme/qgpgmeexportjob.h similarity index 62% copy from lib/backends/chiasmus/chiasmuslibrary.h copy to lib/backends/qgpgme/qgpgmeexportjob.h index 1759b4fc7..8b799b583 100644 --- a/lib/backends/chiasmus/chiasmuslibrary.h +++ b/lib/backends/qgpgme/qgpgmeexportjob.h @@ -1,68 +1,69 @@ -/* -*- mode: C++; c-file-style: "gnu" -*- - chiasmuslibrary.h +/* + qgpgmeexportjob.h This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ +#ifndef __KLEO_QGPGMEEXPORTJOB_H__ +#define __KLEO_QGPGMEEXPORTJOB_H__ -#ifndef __KLEO_CHIASMUSLIBRARY_H__ -#define __KLEO_CHIASMUSLIBRARY_H__ +#include + +#include "qgpgmejob.h" -#include #include -class KLibrary; +namespace GpgME { + class Error; + class Context; +} namespace Kleo { - /** - @short small helper class to load xia.o through xia.so and make - the functionality available. - */ - class ChiasmusLibrary { - ChiasmusLibrary(); - ~ChiasmusLibrary(); + class QGpgMEExportJob : public ExportJob, private QGpgMEJob { + Q_OBJECT QGPGME_JOB public: - static const ChiasmusLibrary * instance(); - static void deleteInstance(); + QGpgMEExportJob( GpgME::Context * context ); + ~QGpgMEExportJob(); - int perform( const QValueVector & args ) const; - private: - typedef int ( *main_func )( int, char** ); - main_func chiasmus( QString * reason=0 ) const; + /*! \reimp from ExportJob */ + GpgME::Error start( const QStringList & patterns ); + + private slots: + void slotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e ) { + QGpgMEJob::doSlotOperationDoneEvent( context, e ); + } private: - static ChiasmusLibrary * self; - mutable KLibrary * mXiaLibrary; + void doOperationDoneEvent( const GpgME::Error & e ); }; } - -#endif // __KLEO_CHIASMUSLIBRARY_H__ +#endif // __KLEO_QGPGMEEXPORTJOB_H__ diff --git a/lib/backends/qgpgme/qgpgmebackend.h b/lib/backends/qgpgme/qgpgmeimportjob.cpp similarity index 50% copy from lib/backends/qgpgme/qgpgmebackend.h copy to lib/backends/qgpgme/qgpgmeimportjob.cpp index 44301c683..fd1251b65 100644 --- a/lib/backends/qgpgme/qgpgmebackend.h +++ b/lib/backends/qgpgme/qgpgmeimportjob.cpp @@ -1,82 +1,86 @@ -/* -*- mode: C++; c-file-style: "gnu" -*- - qgpgmebackend.h +/* + qgpgmeimportjob.cpp This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2004,2005 Klarälvdalens Datakonsult AB + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ +#ifdef HAVE_CONFIG_H +#include +#endif -#ifndef __KLEO_QGPGMEBACKEND_H__ -#define __KLEO_QGPGMEBACKEND_H__ +#include "qgpgmeimportjob.h" -#include "kleo/cryptobackend.h" +#include +#include -class CryptPlugWrapper; +#include +#include +#include -namespace Kleo { - class CryptoConfig; -} -class QGpgMECryptoConfig; -class QString; - -namespace Kleo { +#include - class QGpgMEBackend : public Kleo::CryptoBackend { - public: - QGpgMEBackend(); - ~QGpgMEBackend(); +Kleo::QGpgMEImportJob::QGpgMEImportJob( GpgME::Context * context ) + : ImportJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMEImportJob" ), + QGpgMEJob( this, context ) +{ + assert( context ); +} - QString name() const; - QString displayName() const; +Kleo::QGpgMEImportJob::~QGpgMEImportJob() { +} - CryptoConfig * config() const; +void Kleo::QGpgMEImportJob::setup( const QByteArray & keyData ) { + assert( !mInData ); - Protocol * openpgp() const; - Protocol * smime() const; - Protocol * protocol( const char * name ) const; + createInData( keyData ); +} - bool checkForOpenPGP( QString * reason=0 ) const; - bool checkForSMIME( QString * reason=0 ) const; - bool checkForProtocol( const char * name, QString * reason ) const; +GpgME::Error Kleo::QGpgMEImportJob::start( const QByteArray & keyData ) { + setup( keyData ); - bool supportsOpenPGP() const { return true; } - bool supportsSMIME() const { return true; } - bool supportsProtocol( const char * name ) const; + hookupContextToEventLoopInteractor(); - const char * enumerateProtocols( int i ) const; + const GpgME::Error err = mCtx->startKeyImport( *mInData ); + + if ( err ) + deleteLater(); + return err; +} - private: - mutable QGpgMECryptoConfig * mCryptoConfig; - mutable CryptPlugWrapper * mOpenPGPProtocol; - mutable CryptPlugWrapper * mSMIMEProtocol; - }; +GpgME::ImportResult Kleo::QGpgMEImportJob::exec( const QByteArray & keyData ) { + setup( keyData ); + return mCtx->importKeys( *mInData ); +} +void Kleo::QGpgMEImportJob::doOperationDoneEvent( const GpgME::Error & ) { + emit result( mCtx->importResult() ); } -#endif // __KLEO_QGPGMEBACKEND_H__ +#include "qgpgmeimportjob.moc" diff --git a/lib/backends/chiasmus/chiasmuslibrary.h b/lib/backends/qgpgme/qgpgmeimportjob.h similarity index 59% copy from lib/backends/chiasmus/chiasmuslibrary.h copy to lib/backends/qgpgme/qgpgmeimportjob.h index 1759b4fc7..8c2ee1ad4 100644 --- a/lib/backends/chiasmus/chiasmuslibrary.h +++ b/lib/backends/qgpgme/qgpgmeimportjob.h @@ -1,68 +1,73 @@ -/* -*- mode: C++; c-file-style: "gnu" -*- - chiasmuslibrary.h +/* + qgpgmeimportjob.h This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ +#ifndef __KLEO_QGPGMEIMPORTJOB_H__ +#define __KLEO_QGPGMEIMPORTJOB_H__ -#ifndef __KLEO_CHIASMUSLIBRARY_H__ -#define __KLEO_CHIASMUSLIBRARY_H__ +#include + +#include "qgpgmejob.h" -#include #include -class KLibrary; +namespace GpgME { + class Error; + class Context; +} namespace Kleo { - /** - @short small helper class to load xia.o through xia.so and make - the functionality available. - */ - class ChiasmusLibrary { - ChiasmusLibrary(); - ~ChiasmusLibrary(); + class QGpgMEImportJob : public ImportJob, private QGpgMEJob { + Q_OBJECT QGPGME_JOB public: - static const ChiasmusLibrary * instance(); - static void deleteInstance(); + QGpgMEImportJob( GpgME::Context * context ); + ~QGpgMEImportJob(); - int perform( const QValueVector & args ) const; - private: - typedef int ( *main_func )( int, char** ); - main_func chiasmus( QString * reason=0 ) const; + /*! \reimp from ImportJob */ + GpgME::Error start( const QByteArray & keyData ); + + /*! \reimp from ImportJob */ + GpgME::ImportResult exec( const QByteArray & keyData ); + + private slots: + void slotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e ) { + QGpgMEJob::doSlotOperationDoneEvent( context, e ); + } private: - static ChiasmusLibrary * self; - mutable KLibrary * mXiaLibrary; + void doOperationDoneEvent( const GpgME::Error & e ); + void setup( const QByteArray & ); }; } - -#endif // __KLEO_CHIASMUSLIBRARY_H__ +#endif // __KLEO_QGPGMEIMPORTJOB_H__ diff --git a/lib/backends/qgpgme/qgpgmejob.cpp b/lib/backends/qgpgme/qgpgmejob.cpp new file mode 100644 index 000000000..afd58e301 --- /dev/null +++ b/lib/backends/qgpgme/qgpgmejob.cpp @@ -0,0 +1,285 @@ +/* + qgpgmejob.cpp + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "qgpgmejob.h" +#include "qgpgmeprogresstokenmapper.h" + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include + +#include +#include + +namespace { + class InvarianceChecker { + public: +#ifdef NDEBUG + InvarianceChecker( const Kleo::QGpgMEJob * ) {} +#else + InvarianceChecker( const Kleo::QGpgMEJob * job ) + : _this( job ) + { + assert( _this ); + _this->checkInvariants(); + } + ~InvarianceChecker() { + _this->checkInvariants(); + } + private: + const Kleo::QGpgMEJob * _this; +#endif + }; +} + +Kleo::QGpgMEJob::QGpgMEJob( Kleo::Job * _this, GpgME::Context * context ) + : GpgME::ProgressProvider(), + GpgME::PassphraseProvider(), + mThis( _this ), + mCtx( context ), + mInData( 0 ), + mInDataDataProvider( 0 ), + mOutData( 0 ), + mOutDataDataProvider( 0 ), + mPatterns( 0 ), + mReplacedPattern( 0 ), + mNumPatterns( 0 ), + mChunkSize( 1024 ), + mPatternStartIndex( 0 ), mPatternEndIndex( 0 ) +{ + InvarianceChecker check( this ); + assert( context ); + QObject::connect( QGpgME::EventLoopInteractor::instance(), SIGNAL(aboutToDestroy()), + _this, SLOT(slotCancel()) ); + context->setProgressProvider( this ); + // (mmutz) work around a gpgme bug in versions at least <= 0.9.0. + // These versions will return GPG_ERR_NOT_IMPLEMENTED from + // a CMS sign operation when a passphrase callback is set. + if ( context->protocol() == GpgME::Context::OpenPGP ) + context->setPassphraseProvider( this ); +} + +void Kleo::QGpgMEJob::checkInvariants() const { +#ifndef NDEBUG + if ( mPatterns ) { + assert( mPatterns[mNumPatterns] == 0 ); + if ( mPatternEndIndex > 0 ) { + assert( mPatternEndIndex > mPatternStartIndex ); + assert( mPatternEndIndex - mPatternStartIndex == mChunkSize ); + } else { + assert( mPatternEndIndex == mPatternStartIndex ); + } + if ( mPatternEndIndex < mNumPatterns ) { + assert( mPatterns[mPatternEndIndex] == 0 ); + assert( mReplacedPattern != 0 ); + } else { + assert( mReplacedPattern == 0 ); + } + } else { + assert( mNumPatterns == 0 ); + assert( mPatternStartIndex == 0 ); + assert( mPatternEndIndex == 0 ); + assert( mReplacedPattern == 0 ); + } +#endif +} + +Kleo::QGpgMEJob::~QGpgMEJob() { + InvarianceChecker check( this ); + delete mCtx; mCtx = 0; + delete mInData; mInData = 0; + delete mInDataDataProvider; mInDataDataProvider = 0; + delete mOutData; mOutData = 0; + delete mOutDataDataProvider; mOutDataDataProvider = 0; + deleteAllPatterns(); +} + +void Kleo::QGpgMEJob::deleteAllPatterns() { + if ( mPatterns ) + for ( unsigned int i = 0 ; i < mNumPatterns ; ++i ) + free( (void*)mPatterns[i] ); + free( (void*)mReplacedPattern ); mReplacedPattern = 0; + delete[] mPatterns; mPatterns = 0; + mPatternEndIndex = mPatternStartIndex = mNumPatterns = 0; +} + +void Kleo::QGpgMEJob::hookupContextToEventLoopInteractor() { + mCtx->setManagedByEventLoopInteractor( true ); + QObject::connect( QGpgME::EventLoopInteractor::instance(), + SIGNAL(operationDoneEventSignal(GpgME::Context*,const GpgME::Error&)), + mThis, SLOT(slotOperationDoneEvent(GpgME::Context*,const GpgME::Error&)) ); +} + +void Kleo::QGpgMEJob::setPatterns( const QStringList & sl, bool allowEmpty ) { + InvarianceChecker check( this ); + deleteAllPatterns(); + // create a new null-terminated C array of char* from patterns: + mPatterns = new const char*[ sl.size() + 1 ]; + const char* * pat_it = mPatterns; + mNumPatterns = 0; + for ( QStringList::const_iterator it = sl.begin() ; it != sl.end() ; ++it ) { + if ( (*it).isNull() ) + continue; + if ( (*it).isEmpty() && !allowEmpty ) + continue; + *pat_it++ = strdup( (*it).utf8().data() ); + ++mNumPatterns; + } + *pat_it++ = 0; + mReplacedPattern = 0; + mPatternEndIndex = mChunkSize = mNumPatterns; +} + +void Kleo::QGpgMEJob::setChunkSize( unsigned int chunksize ) { + InvarianceChecker check( this ); + if ( mReplacedPattern ) { + mPatterns[mPatternEndIndex] = mReplacedPattern; + mReplacedPattern = 0; + } + mChunkSize = std::min( chunksize, mNumPatterns ); + mPatternStartIndex = 0; + mPatternEndIndex = mChunkSize; + mReplacedPattern = mPatterns[mPatternEndIndex]; + mPatterns[mPatternEndIndex] = 0; +} + +const char* * Kleo::QGpgMEJob::nextChunk() { + InvarianceChecker check( this ); + if ( mReplacedPattern ) { + mPatterns[mPatternEndIndex] = mReplacedPattern; + mReplacedPattern = 0; + } + mPatternStartIndex += mChunkSize; + mPatternEndIndex += mChunkSize; + if ( mPatternEndIndex < mNumPatterns ) { // could safely be <=, but the last entry is NULL anyway + mReplacedPattern = mPatterns[mPatternEndIndex]; + mPatterns[mPatternEndIndex] = 0; + } + return patterns(); +} + +const char* * Kleo::QGpgMEJob::patterns() const { + InvarianceChecker check( this ); + if ( mPatternStartIndex < mNumPatterns ) + return mPatterns + mPatternStartIndex; + return 0; +} + +GpgME::Error Kleo::QGpgMEJob::setSigningKeys( const std::vector & signers ) { + mCtx->clearSigningKeys(); + for ( std::vector::const_iterator it = signers.begin() ; it != signers.end() ; ++it ) { + if ( (*it).isNull() ) + continue; + if ( const GpgME::Error err = mCtx->addSigningKey( *it ) ) + return err; + } + return 0; +} + +void Kleo::QGpgMEJob::createInData( const QByteArray & in ) { + mInDataDataProvider = new QGpgME::QByteArrayDataProvider( in ); + mInData = new GpgME::Data( mInDataDataProvider ); + assert( !mInData->isNull() ); +} + +void Kleo::QGpgMEJob::createOutData() { + mOutDataDataProvider = new QGpgME::QByteArrayDataProvider(); + mOutData = new GpgME::Data( mOutDataDataProvider ); + assert( !mOutData->isNull() ); +} + +void Kleo::QGpgMEJob::doSlotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e ) { + if ( context == mCtx ) { + doEmitDoneSignal(); + doOperationDoneEvent( e ); + mThis->deleteLater(); + } +} + +void Kleo::QGpgMEJob::doSlotCancel() { + mCtx->cancelPendingOperation(); +} + +void Kleo::QGpgMEJob::showProgress( const char * what, int type, int current, int total ) { + doEmitProgressSignal( QGpgMEProgressTokenMapper::instance()->map( what, type, current, total ), current, total ); +} + +char * Kleo::QGpgMEJob::getPassphrase( const char * useridHint, const char * /*description*/, + bool previousWasBad, bool & canceled ) { + // DF: here, description is the key fingerprint, twice, then "17 0". Not really descriptive. + // So I'm ignoring QString::fromLocal8Bit( description ) ) + QString msg = previousWasBad ? + i18n( "You need a passphrase to unlock the secret key for user:
%1 (retry)" ) : + i18n( "You need a passphrase to unlock the secret key for user:
%1" ); + msg = msg.arg( QString::fromUtf8( useridHint ) ) + "

"; + msg.prepend( "" ); + msg += i18n( "This dialog will reappear every time the passphrase is needed. For a more secure solution that also allows caching the passphrase, use gpg-agent." ) + "
"; + const QString gpgAgent = KStandardDirs::findExe( "gpg-agent" ); + if ( !gpgAgent.isEmpty() ) { + msg += i18n( "gpg-agent was found in %1, but does not appear to be running." ) + .arg( gpgAgent ); + } else { + msg += i18n( "gpg-agent is part of gnupg-%1, which you can download from %2" ) + .arg( "1.9" ) + .arg( "http://www.gnupg.org/download" ); // add #gnupg2 if you can make this a real link + } + msg += "
"; + msg += i18n( "For information on how to set up gpg-agent, see %1" ) + .arg( "http://kmail.kde.org/kmail-pgpmime-howto.html" ); + msg += "

"; + msg += i18n( "Enter passphrase:" ); + Kleo::PassphraseDialog dlg( msg, i18n("Passphrase Dialog") ); + if ( dlg.exec() != QDialog::Accepted ) { + canceled = true; + return 0; + } + canceled = false; + // gpgme++ free()s it, and we need to copy as long as dlg isn't deleted :o + return strdup( dlg.passphrase() ); +} diff --git a/lib/backends/qgpgme/qgpgmejob.h b/lib/backends/qgpgme/qgpgmejob.h new file mode 100644 index 000000000..aff16ce90 --- /dev/null +++ b/lib/backends/qgpgme/qgpgmejob.h @@ -0,0 +1,154 @@ +/* + qgpgmejob.h + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifndef __KLEO_QGPGMEJOB_H__ +#define __KLEO_QGPGMEJOB_H__ + +#include +#include + +#include + +#include + +#include +#include + +namespace GpgME { + class Error; + class Context; + class Data; +} + +namespace Kleo { + class Job; +} + +namespace QGpgME { + class QByteArrayDataProvider; +} + +class QString; +class QStringList; + +namespace Kleo { + + /** This is a hackish helper class to avoid code duplication in this + backend's Kleo::Job subclasses. It contains several workarounds + for moc/signal/slot shortcomings, most of which the author of + this thinks are Qt bugs (lazy implementations), first and + foremost the inability of moc to handle inheritance from + multiple QObject-derived subclasses. + + To use it, inherit from the Job-subclass, then from this class, + add QGPGME_JOB to just after Q OBJECT and implement + doOperationDoneEvent() by emitting your variant of the result() + signal there. Pass "this" as the first argument this QGpgMEJOb's + ctor. The rest is dealt with automatically. + */ + class KDE_EXPORT QGpgMEJob : public GpgME::ProgressProvider, public GpgME::PassphraseProvider { + public: + QGpgMEJob( Kleo::Job * _this, GpgME::Context * context ); + ~QGpgMEJob(); + + protected: + /*! Called on operation-done events, between emitting done() and + calling deleteLater(). You should emit your result signal here. */ + virtual void doOperationDoneEvent( const GpgME::Error & e ) = 0; + /*! Hooks up mCtx to be managed by the event loop interactor */ + void hookupContextToEventLoopInteractor(); + /*! Fills mPatterns from the stringlist, resets chunking to the full list */ + void setPatterns( const QStringList & sl, bool allowEmpty=false ); + /*! Returnes the number of patterns set */ + unsigned int numPatterns() const { return mNumPatterns; } + /*! Skips to the next chunk of patterns. @return patterns() */ + const char* * nextChunk(); + /*! @return patterns, offset by the current chunk */ + const char* * patterns() const; + /*! Set the current pattern chunksize to size and reset the chunk index to zero */ + void setChunkSize( unsigned int size ); + /*! @return current chunksize */ + unsigned int chunkSize() const { return mChunkSize; } + /*! Creates an empty GpgME::Data/QGpgME::QByteArrayDataProvider pair */ + void createOutData(); + /*! Creates a GpgME::Data/QGpgME::QByteArrayDataProvider pair, + filled with the contents of \a in */ + void createInData( const QByteArray & in ); + /*! Sets the list of signing keys */ + GpgME::Error setSigningKeys( const std::vector & signers ); + /*! Call this to implement a slotOperationDoneEvent() */ + void doSlotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e ); + + // + // only boring stuff below this line... + // + + protected: + virtual void doEmitProgressSignal( const QString & what, int current, int total ) = 0; + virtual void doEmitDoneSignal() = 0; + void doSlotCancel(); + + private: + /*! \reimp from GpgME::ProgressProvider */ + void showProgress( const char * what, int type, int current, int total ); + char * getPassphrase( const char * useridHint, const char * description, + bool previousWasBad, bool & canceled ); + void deleteAllPatterns(); + + public: + void checkInvariants() const; + + protected: + Kleo::Job * mThis; + GpgME::Context * mCtx; + GpgME::Data * mInData; + QGpgME::QByteArrayDataProvider * mInDataDataProvider; + GpgME::Data * mOutData; + QGpgME::QByteArrayDataProvider * mOutDataDataProvider; + private: + const char* * mPatterns; + // holds the entry - if any - in mPattern that was replaced with + // NULL to create a temporary end-of-array marker for gpgme: + const char * mReplacedPattern; + unsigned int mNumPatterns; + unsigned int mChunkSize; + unsigned int mPatternStartIndex, mPatternEndIndex; + }; + +} + +#define make_slot_cancel private: void slotCancel() { QGpgMEJob::doSlotCancel(); } +#define make_progress_emitter private: void doEmitProgressSignal( const QString & what, int cur, int tot ) { emit progress( what, cur, tot ); } +#define make_done_emitter private: void doEmitDoneSignal() { emit done(); } +#define QGPGME_JOB make_slot_cancel make_progress_emitter make_done_emitter + +#endif // __KLEO_QGPGMEJOB_H__ diff --git a/lib/backends/qgpgme/qgpgmekeygenerationjob.cpp b/lib/backends/qgpgme/qgpgmekeygenerationjob.cpp new file mode 100644 index 000000000..a0ab78f23 --- /dev/null +++ b/lib/backends/qgpgme/qgpgmekeygenerationjob.cpp @@ -0,0 +1,86 @@ +/* + qgpgmekeygenerationjob.cpp + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "qgpgmekeygenerationjob.h" + +#include +#include + +#include +#include +#include + +#include + +Kleo::QGpgMEKeyGenerationJob::QGpgMEKeyGenerationJob( GpgME::Context * context ) + : KeyGenerationJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMEKeyGenerationJob" ), + QGpgMEJob( this, context ), + mPubKeyDataProvider( 0 ), + mPubKey( 0 ) +{ + assert( context ); +} + +Kleo::QGpgMEKeyGenerationJob::~QGpgMEKeyGenerationJob() { + delete mPubKey; mPubKey = 0; + delete mPubKeyDataProvider; mPubKeyDataProvider = 0; +} + +GpgME::Error Kleo::QGpgMEKeyGenerationJob::start( const QString & parameters ) { + assert( !mPubKey ); + + // set up empty data object for the public key data + if ( mCtx->protocol() == GpgME::Context::CMS ) { + mPubKeyDataProvider = new QGpgME::QByteArrayDataProvider(); + mPubKey = new GpgME::Data( mPubKeyDataProvider ); + assert( !mPubKey->isNull() ); + } + + hookupContextToEventLoopInteractor(); + + const GpgME::Error err = + mCtx->startKeyGeneration( parameters.utf8().data(), mPubKey ? *mPubKey : GpgME::Data::null ); + + if ( err ) + deleteLater(); + return err; +} + +void Kleo::QGpgMEKeyGenerationJob::doOperationDoneEvent( const GpgME::Error & ) { + emit result( mCtx->keyGenerationResult(), mPubKeyDataProvider ? mPubKeyDataProvider->data() : QByteArray() ); +} + +#include "qgpgmekeygenerationjob.moc" diff --git a/lib/backends/chiasmus/chiasmuslibrary.h b/lib/backends/qgpgme/qgpgmekeygenerationjob.h similarity index 55% copy from lib/backends/chiasmus/chiasmuslibrary.h copy to lib/backends/qgpgme/qgpgmekeygenerationjob.h index 1759b4fc7..973aeb12d 100644 --- a/lib/backends/chiasmus/chiasmuslibrary.h +++ b/lib/backends/qgpgme/qgpgmekeygenerationjob.h @@ -1,68 +1,78 @@ -/* -*- mode: C++; c-file-style: "gnu" -*- - chiasmuslibrary.h +/* + qgpgmekeygenerationjob.h This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ +#ifndef __KLEO_QGPGMEKEYGENERATIONJOB_H__ +#define __KLEO_QGPGMEKEYGENERATIONJOB_H__ -#ifndef __KLEO_CHIASMUSLIBRARY_H__ -#define __KLEO_CHIASMUSLIBRARY_H__ +#include -#include -#include +#include "qgpgmejob.h" +#include -class KLibrary; +namespace GpgME { + class Error; + class Context; + class Key; + class Data; +} + +namespace QGpgME { + class QByteArrayDataProvider; +} namespace Kleo { - /** - @short small helper class to load xia.o through xia.so and make - the functionality available. - */ - class ChiasmusLibrary { - ChiasmusLibrary(); - ~ChiasmusLibrary(); + class KDE_EXPORT QGpgMEKeyGenerationJob : public KeyGenerationJob, private QGpgMEJob { + Q_OBJECT QGPGME_JOB public: - static const ChiasmusLibrary * instance(); - static void deleteInstance(); + QGpgMEKeyGenerationJob( GpgME::Context * context ); + ~QGpgMEKeyGenerationJob(); + + /*! \reimp from KeygenerationJob */ + GpgME::Error start( const QString & parameters ); + + private slots: + void slotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & error ) { + QGpgMEJob::doSlotOperationDoneEvent( context, error ); + } - int perform( const QValueVector & args ) const; private: - typedef int ( *main_func )( int, char** ); - main_func chiasmus( QString * reason=0 ) const; + void doOperationDoneEvent( const GpgME::Error & e ); private: - static ChiasmusLibrary * self; - mutable KLibrary * mXiaLibrary; + QGpgME::QByteArrayDataProvider * mPubKeyDataProvider; + GpgME::Data * mPubKey; }; } - -#endif // __KLEO_CHIASMUSLIBRARY_H__ +#endif // __KLEO_QGPGMEKEYGENERATIONJOB_H__ diff --git a/lib/backends/qgpgme/qgpgmekeylistjob.cpp b/lib/backends/qgpgme/qgpgmekeylistjob.cpp index 68578123b..9c87e3ef6 100644 --- a/lib/backends/qgpgme/qgpgmekeylistjob.cpp +++ b/lib/backends/qgpgme/qgpgmekeylistjob.cpp @@ -1,187 +1,187 @@ /* qgpgmekeylistjob.cpp This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifdef HAVE_CONFIG_H #include #endif #include "qgpgmekeylistjob.h" #include #include #include #include #include #include #include #include #include #include #include #include #include Kleo::QGpgMEKeyListJob::QGpgMEKeyListJob( GpgME::Context * context ) : KeyListJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMEKeyListJob" ), QGpgMEJob( this, context ), mResult(), mSecretOnly( false ) { assert( context ); } Kleo::QGpgMEKeyListJob::~QGpgMEKeyListJob() { } void Kleo::QGpgMEKeyListJob::setup( const QStringList & pats, bool secretOnly ) { assert( !patterns() ); mSecretOnly = secretOnly; setPatterns( pats ); } GpgME::Error Kleo::QGpgMEKeyListJob::start( const QStringList & pats, bool secretOnly ) { setup( pats, secretOnly ); hookupContextToEventLoopInteractor(); connect( QGpgME::EventLoopInteractor::instance(), SIGNAL(nextKeyEventSignal(GpgME::Context*,const GpgME::Key&)), SLOT(slotNextKeyEvent(GpgME::Context*,const GpgME::Key&)) ); // The communication channel between gpgme and gpgsm is limited in // the number of patterns that can be transported, but they won't // say to how much, so we need to find out ourselves if we get a // LINE_TOO_LONG error back... // We could of course just feed them single patterns, and that would // probably be easier, but the performance penalty would currently // be noticable. while ( const GpgME::Error err = mCtx->startKeyListing( patterns(), mSecretOnly ) ) { if ( err.code() == GPG_ERR_LINE_TOO_LONG ) { setChunkSize( chunkSize()/2 ); if ( chunkSize() >= 1 ) { kdDebug(5150) << "QGpgMEKeyListJob::start(): retrying keylisting with chunksize " << chunkSize() << endl; continue; } } deleteLater(); mResult = GpgME::KeyListResult( 0, err ); return err; } mResult = GpgME::KeyListResult( 0, 0 ); return 0; } GpgME::KeyListResult Kleo::QGpgMEKeyListJob::exec( const QStringList & pats, bool secretOnly, std::vector & keys ) { setup( pats, secretOnly ); // The communication channel between gpgme and gpgsm is limited in // the number of patterns that can be transported, but they won't // say to how much, so we need to find out ourselves if we get a // LINE_TOO_LONG error back... // We could of course just feed them single patterns, and that would // probably be easier, but the performance penalty would currently // be noticable. for (;;) { keys.clear(); mResult = attemptSyncKeyListing( keys ); if ( !mResult.error() || mResult.error().code() != GPG_ERR_LINE_TOO_LONG ) return mResult; // got LINE_TOO_LONG, try a smaller chunksize: setChunkSize( chunkSize()/2 ); if ( chunkSize() < 1 ) // chunks smaller than one can't be -> return the error. return mResult; kdDebug(5150) << "QGpgMEKeyListJob::exec(): retrying keylisting with chunksize " << chunkSize() << endl; } kdFatal(5150) << "QGpgMEKeyListJob::exec(): Oops, this is not supposed to happen!" << endl; return GpgME::KeyListResult(); } GpgME::KeyListResult Kleo::QGpgMEKeyListJob::attemptSyncKeyListing( std::vector & keys ) { GpgME::KeyListResult result; for ( const char* * chunk = patterns() ; chunk ; chunk = nextChunk() ) { if ( const GpgME::Error err = mCtx->startKeyListing( chunk, mSecretOnly ) ) return GpgME::KeyListResult( 0, err ); GpgME::Error err; do keys.push_back( mCtx->nextKey( err ) ); while ( !err ); keys.pop_back(); result.mergeWith( mCtx->endKeyListing() ); if ( result.error() ) break; } return result; } void Kleo::QGpgMEKeyListJob::slotNextKeyEvent( GpgME::Context * context, const GpgME::Key & key ) { if ( context == mCtx ) emit nextKey( key ); } void Kleo::QGpgMEKeyListJob::slotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & ) { if ( context != mCtx ) return; mResult.mergeWith( mCtx->keyListResult() ); if ( !mResult.error() ) if ( const char* * chunk = nextChunk() ) { if ( const GpgME::Error err = mCtx->startKeyListing( chunk, mSecretOnly ) ) mResult.mergeWith( GpgME::KeyListResult( 0, err ) ); else return; } emit done(); emit result( mResult ); deleteLater(); } void Kleo::QGpgMEKeyListJob::showErrorDialog( QWidget * parent, const QString & caption ) const { if ( !mResult.error() || mResult.error().isCanceled() ) return; const QString msg = i18n( "

An error occurred while fetching " "the keys from the backend:

" "

%1

" ) .arg( QString::fromLocal8Bit( mResult.error().asString() ) ); KMessageBox::error( parent, msg, caption ); } #include "qgpgmekeylistjob.moc" diff --git a/lib/kleo/specialjob.h b/lib/backends/qgpgme/qgpgmekeylistjob.h similarity index 50% copy from lib/kleo/specialjob.h copy to lib/backends/qgpgme/qgpgmekeylistjob.h index 106257428..8320e0134 100644 --- a/lib/kleo/specialjob.h +++ b/lib/backends/qgpgme/qgpgmekeylistjob.h @@ -1,86 +1,81 @@ /* - specialjob.h + qgpgmekeylistjob.h This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#ifndef __KLEO_SPECIALJOB_H__ -#define __KLEO_SPECIALJOB_H__ +#ifndef __KLEO_QGPGMEKEYLISTJOB_H__ +#define __KLEO_QGPGMEKEYLISTJOB_H__ -#include "job.h" +#include + +#include + +#include "qgpgmejob.h" namespace GpgME { class Error; + class Context; + class Key; } namespace Kleo { - /** - @short An abstract base class for protocol-specific jobs - - To use a SpecialJob, first obtain an instance from the - CryptoBackend implementation, connect progress() and result() - signals to suitable slots and then start the job with a call to - start(). This call might fail, in which case the SpecialJob - instance will have schedules its own destruction with a call to - QObject::deleteLater(). - - After result() is emitted, the SpecialJob will schedule its own - destruction by calling QObject::deleteLater(). + class QGpgMEKeyListJob : public KeyListJob, private QGpgMEJob { + Q_OBJECT QGPGME_JOB + public: + QGpgMEKeyListJob( GpgME::Context * context ); + ~QGpgMEKeyListJob(); - Parameters are set using the Qt property system. More general, or - constructor parameters are given in the call to - Kleo::CryptoBackend::Protocol::specialJob(). + /*! \reimp from KeyListJob */ + GpgME::Error start( const QStringList & patterns, bool secretOnly ); - The result is made available through the result signal, and - through the read-only result property, the latter of which needs - to be defined in each SpecialJob subclass. - */ - class SpecialJob : public Job { - Q_OBJECT - protected: - SpecialJob( QObject * parent, const char * name ); + /*! \reimp from KeyListJob */ + GpgME::KeyListResult exec( const QStringList & patterns, bool secretOnly, std::vector & keys ); - public: - ~SpecialJob(); + /*! \reimp from Job */ + void showErrorDialog( QWidget * parent, const QString & caption ) const; - /** - Starts the special operation. - */ - virtual GpgME::Error start() = 0; + private slots: + void slotNextKeyEvent( GpgME::Context * context, const GpgME::Key & key ); + void slotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e ); - virtual GpgME::Error exec() = 0; + private: + void doOperationDoneEvent( const GpgME::Error &) {} // unused, we implement slotOperationDoneEvent ourselves. + void setup( const QStringList &, bool ); + GpgME::KeyListResult attemptSyncKeyListing( std::vector & ); - signals: - void result( const GpgME::Error & result, const QVariant & data ); + private: + GpgME::KeyListResult mResult; + bool mSecretOnly; }; } -#endif // __KLEO_SPECIALJOB_H__ +#endif // __KLEO_QGPGMEKEYLISTJOB_H__ diff --git a/lib/backends/qgpgme/qgpgmeprogresstokenmapper.cpp b/lib/backends/qgpgme/qgpgmeprogresstokenmapper.cpp new file mode 100644 index 000000000..792bc2f43 --- /dev/null +++ b/lib/backends/qgpgme/qgpgmeprogresstokenmapper.cpp @@ -0,0 +1,159 @@ +/* -*- mode: C++; c-file-style: "gnu" -*- + qgpgmeprogresstokenmapper.cpp + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "qgpgmeprogresstokenmapper.h" + +#include + +#include + +#include +#include + +struct Desc { + int type; // 0 == fallback + const char * display; // add %1 for useCur ^ useTot and %1 %2 for useCur == useTot == true + bool useCur : 1; + bool useTot : 1; +}; + +static const struct Desc pk_dsa[] = { + { 0, I18N_NOOP("Generating DSA key..."), false, false } +}; + +static const struct Desc pk_elg[] = { + { 0, I18N_NOOP("Generating ElGamal key..."), false, false } +}; + +static const struct Desc primegen[] = { + // FIXME: add all type's? + { 0, I18N_NOOP("Searching for a large prime number..."), false, false } +}; + +static const struct Desc need_entropy[] = { + { 0, I18N_NOOP("Waiting for new entropy from random number generator (you might want to excercise the harddisks or move the mouse)..."), false, false } +}; + +static const struct Desc tick[] = { + { 0, I18N_NOOP("Please wait..."), false, false } +}; + +static const struct Desc starting_agent[] = { + { 0, I18N_NOOP("Starting gpg-agent (you should consider starting a global instance instead)..."), false, false } +}; + +static const struct { + const char * token; + const Desc * desc; + unsigned int numDesc; +} tokens[] = { +#define make_token(x) { #x, x, sizeof(x) / sizeof(*x) } + make_token(pk_dsa), + make_token(pk_elg), + make_token(primegen), + make_token(need_entropy), + make_token(tick), + make_token(starting_agent) +#undef make_token +}; + + + +Kleo::QGpgMEProgressTokenMapper * Kleo::QGpgMEProgressTokenMapper::mSelf = 0; + +const Kleo::QGpgMEProgressTokenMapper * Kleo::QGpgMEProgressTokenMapper::instance() { + if ( !mSelf ) + (void) new QGpgMEProgressTokenMapper(); + return mSelf; +} + +Kleo::QGpgMEProgressTokenMapper::QGpgMEProgressTokenMapper() { + mSelf = this; +} + +Kleo::QGpgMEProgressTokenMapper::~QGpgMEProgressTokenMapper() { + mSelf = 0; +} + +typedef std::map< QString, std::map > Map; + +static const Map & makeMap() { // return a reference to a static to avoid copying + static Map map; + for ( unsigned int i = 0 ; i < sizeof tokens / sizeof *tokens ; ++i ) { + assert( tokens[i].token ); + const QString token = QString::fromLatin1( tokens[i].token ).lower(); + for ( unsigned int j = 0 ; j < tokens[i].numDesc ; ++j ) { + const Desc & desc = tokens[i].desc[j]; + assert( desc.display ); + map[ token ][ desc.type ] = desc; + } + } + return map; +} + +QString Kleo::QGpgMEProgressTokenMapper::map( const char * tokenUtf8, int subtoken, int cur, int tot ) const { + if ( !tokenUtf8 || !*tokenUtf8 ) + return QString::null; + + if ( qstrcmp( tokenUtf8, "file:" ) == 0 ) + return QString::null; // gpgme's job + + return map( QString::fromUtf8( tokenUtf8 ), subtoken, cur, tot ); +} + +QString Kleo::QGpgMEProgressTokenMapper::map( const QString & token, int subtoken, int cur, int tot ) const { + if ( token.startsWith( "file:" ) ) + return QString::null; // gpgme's job + + static const Map & tokenMap = makeMap(); + + const Map::const_iterator it1 = tokenMap.find( token.lower() ); + if ( it1 == tokenMap.end() ) + return token; + std::map::const_iterator it2 = it1->second.find( subtoken ); + if ( it2 == it1->second.end() ) + it2 = it1->second.find( 0 ); + if ( it2 == it1->second.end() ) + return token; + const Desc & desc = it2->second; + QString result = i18n( desc.display ); + if ( desc.useCur ) + result = result.arg( cur ); + if ( desc.useTot ) + result = result.arg( tot ); + return result; +} + diff --git a/lib/kleo/cryptobackend.cpp b/lib/backends/qgpgme/qgpgmeprogresstokenmapper.h similarity index 64% copy from lib/kleo/cryptobackend.cpp copy to lib/backends/qgpgme/qgpgmeprogresstokenmapper.h index 6da71bc9e..d0a8da6c3 100644 --- a/lib/kleo/cryptobackend.cpp +++ b/lib/backends/qgpgme/qgpgmeprogresstokenmapper.h @@ -1,36 +1,58 @@ /* - kleo/cryptobackend.cpp + qgpgmeprogresstokenmapper.h This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#include "cryptobackend.h" -const char Kleo::CryptoBackend::OpenPGP[] = "OpenPGP"; -const char Kleo::CryptoBackend::SMIME[] = "SMIME"; +#ifndef __KLEO_QGPGMEPROGRESSTOKENMAPPER_H__ +#define __KLEO_QGPGMEPROGRESSTOKENMAPPER_H__ + + +class QString; + +namespace Kleo { + + class QGpgMEProgressTokenMapper { + QGpgMEProgressTokenMapper(); + ~QGpgMEProgressTokenMapper(); + public: + static const QGpgMEProgressTokenMapper * instance(); + + QString map( const char * token, int subtoken, int current, int total ) const; + QString map( const QString & token, int subtoken, int current, int total ) const; + + private: + static QGpgMEProgressTokenMapper * mSelf; + }; + +} + + +#endif // __KLEO_QGPGMEPROGRESSTOKENMAPPER_H__ diff --git a/lib/backends/qgpgme/qgpgmesecretkeyexportjob.cpp b/lib/backends/qgpgme/qgpgmerefreshkeysjob.cpp similarity index 54% copy from lib/backends/qgpgme/qgpgmesecretkeyexportjob.cpp copy to lib/backends/qgpgme/qgpgmerefreshkeysjob.cpp index 9922b5c2f..325306e8c 100644 --- a/lib/backends/qgpgme/qgpgmesecretkeyexportjob.cpp +++ b/lib/backends/qgpgme/qgpgmerefreshkeysjob.cpp @@ -1,193 +1,207 @@ /* - qgpgmesecretexportjob.cpp + qgpgmerefreshkeysjob.cpp This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifdef HAVE_CONFIG_H #include #endif -#include "qgpgmesecretkeyexportjob.h" +#include "qgpgmerefreshkeysjob.h" #include "gnupgprocessbase.h" #include "qgpgmeprogresstokenmapper.h" #include #include -#include #include #include #include -#include #include -Kleo::QGpgMESecretKeyExportJob::QGpgMESecretKeyExportJob( bool armour ) - : ExportJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMESecretKeyExportJob" ), +Kleo::QGpgMERefreshKeysJob::QGpgMERefreshKeysJob() + : RefreshKeysJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMERefreshKeysJob" ), mProcess( 0 ), - mError( 0 ), - mArmour( armour ) + mError( 0 ) { } -Kleo::QGpgMESecretKeyExportJob::~QGpgMESecretKeyExportJob() { +Kleo::QGpgMERefreshKeysJob::~QGpgMERefreshKeysJob() { } -GpgME::Error Kleo::QGpgMESecretKeyExportJob::start( const QStringList & patterns ) { - assert( mKeyData.isEmpty() ); +GpgME::Error Kleo::QGpgMERefreshKeysJob::start( const QStringList & patterns ) { + assert( mPatternsToDo.empty() ); - if ( patterns.size() != 1 || patterns.front().isEmpty() ) { - deleteLater(); - return mError = gpg_err_make( GPG_ERR_SOURCE_GPGSM, GPG_ERR_INV_VALUE ); - } + mPatternsToDo = patterns; + if ( mPatternsToDo.empty() ) + mPatternsToDo.push_back( " " ); // empty list means all -> mae + // sure to fail the first + // startAProcess() guard clause + + return startAProcess(); +} +#if MAX_CMD_LENGTH < 65 + 128 +#error MAX_CMD_LENGTH is too low +#endif + +GpgME::Error Kleo::QGpgMERefreshKeysJob::startAProcess() { + if ( mPatternsToDo.empty() ) + return 0; // create and start gpgsm process: - mProcess = new GnuPGProcessBase( this, "gpgsm --export-secret-key-p12" ); + mProcess = new GnuPGProcessBase( this, "gpgsm -k --with-validation --force-crl-refresh --enable-crl-checks" ); // FIXME: obbtain the path to gpgsm from gpgme, so we use the same instance. - *mProcess << "gpgsm" << "--export-secret-key-p12"; - if ( mArmour ) - *mProcess << "--armor"; - *mProcess << patterns.front().utf8(); + *mProcess << "gpgsm" << "-k" << "--with-validation" << "--force-crl-refresh" + << "--enable-crl-checks"; + unsigned int commandLineLength = MAX_CMD_LENGTH; + commandLineLength -= + strlen("gpgsm") + 1 + strlen("-k") + 1 + + strlen("--with-validation") + 1 + strlen("--force-crl-refresh") + 1 + + strlen("--enable-crl-checks") + 1; + while ( !mPatternsToDo.empty() ) { + const QCString pat = mPatternsToDo.front().utf8().stripWhiteSpace(); + const unsigned int patLength = pat.length(); + if ( patLength >= commandLineLength ) + break; + mPatternsToDo.pop_front(); + if ( pat.isEmpty() ) + continue; + *mProcess << pat; + commandLineLength -= patLength + 1; + } mProcess->setUseStatusFD( true ); connect( mProcess, SIGNAL(processExited(KProcess*)), SLOT(slotProcessExited(KProcess*)) ); - connect( mProcess, SIGNAL(receivedStdout(KProcess*,char*,int)), - SLOT(slotStdout(KProcess*,char*,int)) ); connect( mProcess, SIGNAL(receivedStderr(KProcess*,char*,int)), SLOT(slotStderr(KProcess*,char*,int)) ); connect( mProcess, SIGNAL(status(Kleo::GnuPGProcessBase*,const QString&,const QStringList&)), SLOT(slotStatus(Kleo::GnuPGProcessBase*,const QString&,const QStringList&)) ); - if ( !mProcess->start( KProcess::NotifyOnExit, KProcess::AllOutput ) ) { + if ( !mProcess->start( KProcess::NotifyOnExit, KProcess::Stderr ) ) { mError = gpg_err_make( GPG_ERR_SOURCE_GPGSM, GPG_ERR_ENOENT ); // what else? deleteLater(); return mError; } else return 0; } -void Kleo::QGpgMESecretKeyExportJob::slotCancel() { +void Kleo::QGpgMERefreshKeysJob::slotCancel() { if ( mProcess ) mProcess->kill(); mProcess = 0; mError = gpg_err_make( GPG_ERR_SOURCE_GPGSM, GPG_ERR_CANCELED ); } -void Kleo::QGpgMESecretKeyExportJob::slotStatus( GnuPGProcessBase * proc, const QString & type, const QStringList & args ) { +void Kleo::QGpgMERefreshKeysJob::slotStatus( GnuPGProcessBase * proc, const QString & type, const QStringList & args ) { if ( proc != mProcess ) return; QStringList::const_iterator it = args.begin(); bool ok = false; if ( type == "ERROR" ) { if ( args.size() < 2 ) { - kdDebug( 5150 ) << "Kleo::QGpgMESecretKeyExportJob::slotStatus() not recognising ERROR with < 2 args!" << endl; + kdDebug( 5150 ) << "Kleo::QGpgMERefreshKeysJob::slotStatus() not recognising ERROR with < 2 args!" << endl; return; } const int source = (*++it).toInt( &ok ); if ( !ok ) { - kdDebug( 5150 ) << "Kleo::QGpgMESecretKeyExportJob::slotStatus() expected number for first ERROR arg, got something else" << endl; + kdDebug( 5150 ) << "Kleo::QGpgMERefreshKeysJob::slotStatus() expected number for first ERROR arg, got something else" << endl; return; } ok = false; const int code = (*++it).toInt( &ok ); if ( !ok ) { - kdDebug( 5150 ) << "Kleo::QGpgMESecretKeyExportJob::slotStatus() expected number for second ERROR arg, got something else" << endl; + kdDebug( 5150 ) << "Kleo::QGpgMERefreshKeysJob::slotStatus() expected number for second ERROR arg, got something else" << endl; return; } mError = gpg_err_make( (gpg_err_source_t)source, (gpg_err_code_t)code ); } else if ( type == "PROGRESS" ) { if ( args.size() < 4 ) { - kdDebug( 5150 ) << "Kleo::QGpgMESecretKeyExportJob::slotStatus() not recognising PROGRESS with < 4 args!" << endl; + kdDebug( 5150 ) << "Kleo::QGpgMERefreshKeysJob::slotStatus() not recognising PROGRESS with < 4 args!" << endl; return; } const QString what = *++it; ++it; // don't use "type"... const int cur = (*++it).toInt( &ok ); if ( !ok ) { - kdDebug( 5150 ) << "Kleo::QGpgMESecretKeyExportJob::slotStatus() expected number for \"cur\", got something else" << endl; + kdDebug( 5150 ) << "Kleo::QGpgMERefreshKeysJob::slotStatus() expected number for \"cur\", got something else" << endl; return; } ok = false; const int total = (*++it).toInt( &ok ); if ( !ok ) { - kdDebug( 5150 ) << "Kleo::QGpgMESecretKeyExportJob::slotStatus() expected number for \"total\", got something else" << endl; + kdDebug( 5150 ) << "Kleo::QGpgMERefreshKeysJob::slotStatus() expected number for \"total\", got something else" << endl; return; } emit progress( QGpgMEProgressTokenMapper::instance()->map( what, 0, cur, total ), cur, total ); } } -void Kleo::QGpgMESecretKeyExportJob::slotStdout( KProcess * proc, char * buf, int buflen ) { - if ( proc != mProcess ) - return; - if ( buflen <= 0 ) - return; - if ( !buf ) - return; - const unsigned int oldlen = mKeyData.size(); - mKeyData.resize( oldlen + buflen ); - memcpy( mKeyData.data() + oldlen, buf, buflen ); -} - -void Kleo::QGpgMESecretKeyExportJob::slotStderr( KProcess *, char *, int ) { +void Kleo::QGpgMERefreshKeysJob::slotStderr( KProcess *, char *, int ) { // implement? or not? } -void Kleo::QGpgMESecretKeyExportJob::slotProcessExited( KProcess * proc ) { +void Kleo::QGpgMERefreshKeysJob::slotProcessExited( KProcess * proc ) { if ( proc != mProcess ) return; + if ( !mError && !mPatternsToDo.empty() ) + if ( const GpgME::Error err = startAProcess() ) + mError = err; + else + return; + emit done(); if ( !mError && ( !mProcess->normalExit() || mProcess->exitStatus() != 0 ) ) mError = gpg_err_make( GPG_ERR_SOURCE_GPGSM, GPG_ERR_GENERAL ); - emit result( mError, mKeyData ); + emit result( mError ); deleteLater(); } -#include "qgpgmesecretkeyexportjob.moc" +#include "qgpgmerefreshkeysjob.moc" diff --git a/lib/backends/chiasmus/chiasmuslibrary.h b/lib/backends/qgpgme/qgpgmerefreshkeysjob.h similarity index 58% copy from lib/backends/chiasmus/chiasmuslibrary.h copy to lib/backends/qgpgme/qgpgmerefreshkeysjob.h index 1759b4fc7..a0132f223 100644 --- a/lib/backends/chiasmus/chiasmuslibrary.h +++ b/lib/backends/qgpgme/qgpgmerefreshkeysjob.h @@ -1,68 +1,80 @@ -/* -*- mode: C++; c-file-style: "gnu" -*- - chiasmuslibrary.h +/* + qgpgmerefreshkeysjob.h This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ +#ifndef __KLEO_QGPGMEREFRESHKEYSJOB_H__ +#define __KLEO_QGPGMEREFRESHKEYSJOB_H__ -#ifndef __KLEO_CHIASMUSLIBRARY_H__ -#define __KLEO_CHIASMUSLIBRARY_H__ +#include -#include -#include +#include -class KLibrary; +namespace Kleo { + class GnuPGProcessBase; +} + +namespace GpgME { + class Error; +} + +class KProcess; namespace Kleo { - /** - @short small helper class to load xia.o through xia.so and make - the functionality available. - */ - class ChiasmusLibrary { - ChiasmusLibrary(); - ~ChiasmusLibrary(); + class QGpgMERefreshKeysJob : public RefreshKeysJob { + Q_OBJECT public: - static const ChiasmusLibrary * instance(); - static void deleteInstance(); + QGpgMERefreshKeysJob(); + ~QGpgMERefreshKeysJob(); + + /*! \reimp from RefreshKeysJob */ + GpgME::Error start( const QStringList & patterns ); + + private slots: + /*! \reimp from Job */ + void slotCancel(); + + void slotStatus( Kleo::GnuPGProcessBase *, const QString &, const QStringList & ); + void slotStderr( KProcess *, char *, int ); + void slotProcessExited( KProcess * ); - int perform( const QValueVector & args ) const; private: - typedef int ( *main_func )( int, char** ); - main_func chiasmus( QString * reason=0 ) const; + GpgME::Error startAProcess(); private: - static ChiasmusLibrary * self; - mutable KLibrary * mXiaLibrary; + GnuPGProcessBase * mProcess; + int mError; + QStringList mPatternsToDo; }; } - -#endif // __KLEO_CHIASMUSLIBRARY_H__ +#endif // __KLEO_QGPGMEREFRESHKEYSJOB_H__ diff --git a/lib/backends/qgpgme/qgpgmesecretkeyexportjob.cpp b/lib/backends/qgpgme/qgpgmesecretkeyexportjob.cpp index 9922b5c2f..afc51b5e2 100644 --- a/lib/backends/qgpgme/qgpgmesecretkeyexportjob.cpp +++ b/lib/backends/qgpgme/qgpgmesecretkeyexportjob.cpp @@ -1,193 +1,193 @@ /* qgpgmesecretexportjob.cpp This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifdef HAVE_CONFIG_H #include #endif #include "qgpgmesecretkeyexportjob.h" #include "gnupgprocessbase.h" #include "qgpgmeprogresstokenmapper.h" #include #include #include #include #include #include #include #include Kleo::QGpgMESecretKeyExportJob::QGpgMESecretKeyExportJob( bool armour ) : ExportJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMESecretKeyExportJob" ), mProcess( 0 ), mError( 0 ), mArmour( armour ) { } Kleo::QGpgMESecretKeyExportJob::~QGpgMESecretKeyExportJob() { } GpgME::Error Kleo::QGpgMESecretKeyExportJob::start( const QStringList & patterns ) { assert( mKeyData.isEmpty() ); if ( patterns.size() != 1 || patterns.front().isEmpty() ) { deleteLater(); return mError = gpg_err_make( GPG_ERR_SOURCE_GPGSM, GPG_ERR_INV_VALUE ); } // create and start gpgsm process: mProcess = new GnuPGProcessBase( this, "gpgsm --export-secret-key-p12" ); // FIXME: obbtain the path to gpgsm from gpgme, so we use the same instance. *mProcess << "gpgsm" << "--export-secret-key-p12"; if ( mArmour ) *mProcess << "--armor"; *mProcess << patterns.front().utf8(); mProcess->setUseStatusFD( true ); connect( mProcess, SIGNAL(processExited(KProcess*)), SLOT(slotProcessExited(KProcess*)) ); connect( mProcess, SIGNAL(receivedStdout(KProcess*,char*,int)), SLOT(slotStdout(KProcess*,char*,int)) ); connect( mProcess, SIGNAL(receivedStderr(KProcess*,char*,int)), SLOT(slotStderr(KProcess*,char*,int)) ); connect( mProcess, SIGNAL(status(Kleo::GnuPGProcessBase*,const QString&,const QStringList&)), SLOT(slotStatus(Kleo::GnuPGProcessBase*,const QString&,const QStringList&)) ); if ( !mProcess->start( KProcess::NotifyOnExit, KProcess::AllOutput ) ) { mError = gpg_err_make( GPG_ERR_SOURCE_GPGSM, GPG_ERR_ENOENT ); // what else? deleteLater(); return mError; } else return 0; } void Kleo::QGpgMESecretKeyExportJob::slotCancel() { if ( mProcess ) mProcess->kill(); mProcess = 0; mError = gpg_err_make( GPG_ERR_SOURCE_GPGSM, GPG_ERR_CANCELED ); } void Kleo::QGpgMESecretKeyExportJob::slotStatus( GnuPGProcessBase * proc, const QString & type, const QStringList & args ) { if ( proc != mProcess ) return; QStringList::const_iterator it = args.begin(); bool ok = false; if ( type == "ERROR" ) { if ( args.size() < 2 ) { kdDebug( 5150 ) << "Kleo::QGpgMESecretKeyExportJob::slotStatus() not recognising ERROR with < 2 args!" << endl; return; } const int source = (*++it).toInt( &ok ); if ( !ok ) { kdDebug( 5150 ) << "Kleo::QGpgMESecretKeyExportJob::slotStatus() expected number for first ERROR arg, got something else" << endl; return; } ok = false; const int code = (*++it).toInt( &ok ); if ( !ok ) { kdDebug( 5150 ) << "Kleo::QGpgMESecretKeyExportJob::slotStatus() expected number for second ERROR arg, got something else" << endl; return; } mError = gpg_err_make( (gpg_err_source_t)source, (gpg_err_code_t)code ); } else if ( type == "PROGRESS" ) { if ( args.size() < 4 ) { kdDebug( 5150 ) << "Kleo::QGpgMESecretKeyExportJob::slotStatus() not recognising PROGRESS with < 4 args!" << endl; return; } const QString what = *++it; ++it; // don't use "type"... const int cur = (*++it).toInt( &ok ); if ( !ok ) { kdDebug( 5150 ) << "Kleo::QGpgMESecretKeyExportJob::slotStatus() expected number for \"cur\", got something else" << endl; return; } ok = false; const int total = (*++it).toInt( &ok ); if ( !ok ) { kdDebug( 5150 ) << "Kleo::QGpgMESecretKeyExportJob::slotStatus() expected number for \"total\", got something else" << endl; return; } emit progress( QGpgMEProgressTokenMapper::instance()->map( what, 0, cur, total ), cur, total ); } } void Kleo::QGpgMESecretKeyExportJob::slotStdout( KProcess * proc, char * buf, int buflen ) { if ( proc != mProcess ) return; if ( buflen <= 0 ) return; if ( !buf ) return; const unsigned int oldlen = mKeyData.size(); mKeyData.resize( oldlen + buflen ); memcpy( mKeyData.data() + oldlen, buf, buflen ); } void Kleo::QGpgMESecretKeyExportJob::slotStderr( KProcess *, char *, int ) { // implement? or not? } void Kleo::QGpgMESecretKeyExportJob::slotProcessExited( KProcess * proc ) { if ( proc != mProcess ) return; emit done(); if ( !mError && ( !mProcess->normalExit() || mProcess->exitStatus() != 0 ) ) mError = gpg_err_make( GPG_ERR_SOURCE_GPGSM, GPG_ERR_GENERAL ); emit result( mError, mKeyData ); deleteLater(); } #include "qgpgmesecretkeyexportjob.moc" diff --git a/lib/backends/chiasmus/chiasmuslibrary.h b/lib/backends/qgpgme/qgpgmesecretkeyexportjob.h similarity index 56% copy from lib/backends/chiasmus/chiasmuslibrary.h copy to lib/backends/qgpgme/qgpgmesecretkeyexportjob.h index 1759b4fc7..dca23d7b6 100644 --- a/lib/backends/chiasmus/chiasmuslibrary.h +++ b/lib/backends/qgpgme/qgpgmesecretkeyexportjob.h @@ -1,68 +1,84 @@ -/* -*- mode: C++; c-file-style: "gnu" -*- - chiasmuslibrary.h +/* + qgpgmesecretkeyexportjob.h This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ +#ifndef __KLEO_QGPGMESECRETKEYEXPORTJOB_H__ +#define __KLEO_QGPGMESECRETKEYEXPORTJOB_H__ -#ifndef __KLEO_CHIASMUSLIBRARY_H__ -#define __KLEO_CHIASMUSLIBRARY_H__ +#include -#include #include -class KLibrary; +namespace Kleo { + class GnuPGProcessBase; +} + +namespace GpgME { + class Error; + class Data; +} + +namespace QGpgME { + class QByteArrayDataProvider; +} + +class KProcess; namespace Kleo { - /** - @short small helper class to load xia.o through xia.so and make - the functionality available. - */ - class ChiasmusLibrary { - ChiasmusLibrary(); - ~ChiasmusLibrary(); + class QGpgMESecretKeyExportJob : public ExportJob { + Q_OBJECT public: - static const ChiasmusLibrary * instance(); - static void deleteInstance(); + QGpgMESecretKeyExportJob( bool armour ); + ~QGpgMESecretKeyExportJob(); - int perform( const QValueVector & args ) const; - private: - typedef int ( *main_func )( int, char** ); - main_func chiasmus( QString * reason=0 ) const; + /*! \reimp from ExportJob */ + GpgME::Error start( const QStringList & patterns ); + + private slots: + /*! \reimp from Job */ + void slotCancel(); + + void slotStatus( Kleo::GnuPGProcessBase *, const QString &, const QStringList & ); + void slotStdout( KProcess *, char *, int ); + void slotStderr( KProcess *, char *, int ); + void slotProcessExited( KProcess * ); private: - static ChiasmusLibrary * self; - mutable KLibrary * mXiaLibrary; + GnuPGProcessBase * mProcess; + QByteArray mKeyData; + int mError; + bool mArmour; }; } - -#endif // __KLEO_CHIASMUSLIBRARY_H__ +#endif // __KLEO_QGPGMESECRETKEYEXPORTJOB_H__ diff --git a/lib/backends/qgpgme/qgpgmesignencryptjob.cpp b/lib/backends/qgpgme/qgpgmesignencryptjob.cpp new file mode 100644 index 000000000..1ed6fe0ea --- /dev/null +++ b/lib/backends/qgpgme/qgpgmesignencryptjob.cpp @@ -0,0 +1,123 @@ +/* + qgpgmesignencryptjob.cpp + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "qgpgmesignencryptjob.h" + +#include +#include + +#include +#include + +#include +#include +#include + +#include + +Kleo::QGpgMESignEncryptJob::QGpgMESignEncryptJob( GpgME::Context * context ) + : SignEncryptJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMESignEncryptJob" ), + QGpgMEJob( this, context ) +{ + assert( context ); +} + +Kleo::QGpgMESignEncryptJob::~QGpgMESignEncryptJob() { +} + +GpgME::Error Kleo::QGpgMESignEncryptJob::setup( const std::vector & signers, + const QByteArray & plainText ) { + assert( !mInData ); + assert( !mOutData ); + + createInData( plainText ); + createOutData(); + + return setSigningKeys( signers ); +} + +GpgME::Error Kleo::QGpgMESignEncryptJob::start( const std::vector & signers, + const std::vector & recipients, + const QByteArray & plainText, bool alwaysTrust ) { + if ( const GpgME::Error error = setup( signers, plainText ) ) { + deleteLater(); + return error; + } + + hookupContextToEventLoopInteractor(); + + const GpgME::Context::EncryptionFlags flags = + alwaysTrust ? GpgME::Context::AlwaysTrust : GpgME::Context::None ; + const GpgME::Error err = mCtx->startCombinedSigningAndEncryption( recipients, *mInData, *mOutData, flags ); + + if ( err ) + deleteLater(); + return err; +} + +std::pair +Kleo::QGpgMESignEncryptJob::exec( const std::vector & signers, + const std::vector & recipients, + const QByteArray & plainText, bool alwaysTrust, + QByteArray & cipherText ) { + if ( GpgME::Error err = setup( signers, plainText ) ) + return std::make_pair( GpgME::SigningResult( 0, err ), GpgME::EncryptionResult() ); + const GpgME::Context::EncryptionFlags flags = + alwaysTrust ? GpgME::Context::AlwaysTrust : GpgME::Context::None ; + const std::pair result = + mCtx->signAndEncrypt( recipients, *mInData, *mOutData, flags ); + cipherText = mOutDataDataProvider->data(); + return result; +} + +void Kleo::QGpgMESignEncryptJob::doOperationDoneEvent( const GpgME::Error & ) { + emit result( mCtx->signingResult(), + mCtx->encryptionResult(), + mOutDataDataProvider->data() ); +} + +void Kleo::QGpgMESignEncryptJob::showErrorDialog( QWidget * parent, const QString & caption ) const { + if ( !mResult.first.error() && !mResult.second.error() ) + return; + if ( mResult.first.error().isCanceled() || mResult.second.error().isCanceled() ) + return; + const QString msg = mResult.first.error() + ? i18n("Signing failed: %1" ).arg( QString::fromLocal8Bit( mResult.first.error().asString() ) ) + : i18n("Encryption failed: %1").arg( QString::fromLocal8Bit( mResult.second.error().asString() ) ) ; + KMessageBox::error( parent, msg, caption ); +} + +#include "qgpgmesignencryptjob.moc" diff --git a/lib/backends/qgpgme/qgpgmesignencryptjob.h b/lib/backends/qgpgme/qgpgmesignencryptjob.h new file mode 100644 index 000000000..a826edcbf --- /dev/null +++ b/lib/backends/qgpgme/qgpgmesignencryptjob.h @@ -0,0 +1,91 @@ +/* + qgpgmesignencryptjob.h + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifndef __KLEO_QGPGMESIGNENCRYPTJOB_H__ +#define __KLEO_QGPGMESIGNENCRYPTJOB_H__ + +#include + +#include "qgpgmejob.h" + +#include +#include + +#include + +#include + +#include +namespace GpgME { + class Error; + class Context; + class Key; +} + +namespace Kleo { + + class KDE_EXPORT QGpgMESignEncryptJob : public SignEncryptJob, private QGpgMEJob { + Q_OBJECT QGPGME_JOB + public: + QGpgMESignEncryptJob( GpgME::Context * context ); + ~QGpgMESignEncryptJob(); + + /*! \reimp from SignEncryptJob */ + GpgME::Error start( const std::vector & signers, + const std::vector & recipients, + const QByteArray & plainText, bool alwaysTrust ); + + std::pair + exec( const std::vector & signers, + const std::vector & recipients, + const QByteArray & plainText, bool alwaysTrust, + QByteArray & cipherText ); + + /*! \reimp from Job */ + void showErrorDialog( QWidget * parent, const QString & caption ) const; + + private slots: + void slotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e ) { + QGpgMEJob::doSlotOperationDoneEvent( context, e ); + } + + private: + void doOperationDoneEvent( const GpgME::Error & e ); + GpgME::Error setup( const std::vector &, + const QByteArray & ); + private: + std::pair mResult; + }; + +} + +#endif // __KLEO_QGPGMESIGNENCRYPTJOB_H__ diff --git a/lib/backends/qgpgme/qgpgmesignjob.cpp b/lib/backends/qgpgme/qgpgmesignjob.cpp new file mode 100644 index 000000000..585e898b6 --- /dev/null +++ b/lib/backends/qgpgme/qgpgmesignjob.cpp @@ -0,0 +1,113 @@ +/* + qgpgmesignjob.cpp + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "qgpgmesignjob.h" + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include + +Kleo::QGpgMESignJob::QGpgMESignJob( GpgME::Context * context ) + : SignJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMESignJob" ), + QGpgMEJob( this, context ) +{ + assert( context ); +} + +Kleo::QGpgMESignJob::~QGpgMESignJob() { +} + +GpgME::Error Kleo::QGpgMESignJob::setup( const std::vector & signers, + const QByteArray & plainText ) { + assert( !mInData ); + assert( !mOutData ); + + createInData( plainText ); + createOutData(); + + return setSigningKeys( signers ); +} + +GpgME::Error Kleo::QGpgMESignJob::start( const std::vector & signers, + const QByteArray & plainText, + GpgME::Context::SignatureMode mode ) { + if ( const GpgME::Error error = setup( signers, plainText ) ) { + deleteLater(); + return error; + } + + hookupContextToEventLoopInteractor(); + + const GpgME::Error err = mCtx->startSigning( *mInData, *mOutData, mode ); + + if ( err ) + deleteLater(); + return err; +} + +GpgME::SigningResult Kleo::QGpgMESignJob::exec( const std::vector & signers, + const QByteArray & plainText, + GpgME::Context::SignatureMode mode, + QByteArray & signature ) { + if ( const GpgME::Error err = setup( signers, plainText ) ) + return mResult = GpgME::SigningResult( 0, err ); + mResult = mCtx->sign( *mInData, *mOutData, mode ); + signature = mOutDataDataProvider->data(); + return mResult; +} + +void Kleo::QGpgMESignJob::doOperationDoneEvent( const GpgME::Error & ) { + emit result( mResult, mOutDataDataProvider->data() ); +} + +void Kleo::QGpgMESignJob::showErrorDialog( QWidget * parent, const QString & caption ) const { + if ( !mResult.error() || mResult.error().isCanceled() ) + return; + const QString msg = i18n("Signing failed: %1") + .arg( QString::fromLocal8Bit( mResult.error().asString() ) ); + KMessageBox::error( parent, msg, caption ); +} + +#include "qgpgmesignjob.moc" diff --git a/lib/backends/chiasmus/chiasmuslibrary.h b/lib/backends/qgpgme/qgpgmesignjob.h similarity index 50% copy from lib/backends/chiasmus/chiasmuslibrary.h copy to lib/backends/qgpgme/qgpgmesignjob.h index 1759b4fc7..c2589b477 100644 --- a/lib/backends/chiasmus/chiasmuslibrary.h +++ b/lib/backends/qgpgme/qgpgmesignjob.h @@ -1,68 +1,87 @@ -/* -*- mode: C++; c-file-style: "gnu" -*- - chiasmuslibrary.h +/* + qgpgmesignjob.h This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ +#ifndef __KLEO_QGPGMESIGNJOB_H__ +#define __KLEO_QGPGMESIGNJOB_H__ -#ifndef __KLEO_CHIASMUSLIBRARY_H__ -#define __KLEO_CHIASMUSLIBRARY_H__ +#include + +#include "qgpgmejob.h" + +#include -#include #include -class KLibrary; +namespace GpgME { + class Error; + class Context; + class Key; +} namespace Kleo { - /** - @short small helper class to load xia.o through xia.so and make - the functionality available. - */ - class ChiasmusLibrary { - ChiasmusLibrary(); - ~ChiasmusLibrary(); + class QGpgMESignJob : public SignJob, private QGpgMEJob { + Q_OBJECT QGPGME_JOB public: - static const ChiasmusLibrary * instance(); - static void deleteInstance(); + QGpgMESignJob( GpgME::Context * context ); + ~QGpgMESignJob(); + + /*! \reimp from SignJob */ + GpgME::Error start( const std::vector & signers, + const QByteArray & plainText, + GpgME::Context::SignatureMode mode ); + + /*! \reimp from SignJob */ + GpgME::SigningResult exec( const std::vector & signers, + const QByteArray & plainText, + GpgME::Context::SignatureMode mode, + QByteArray & signature ); + + /*! \reimp from Job */ + void showErrorDialog( QWidget * parent, const QString & caption ) const; + + private slots: + void slotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e ) { + QGpgMEJob::doSlotOperationDoneEvent( context, e ); + } - int perform( const QValueVector & args ) const; private: - typedef int ( *main_func )( int, char** ); - main_func chiasmus( QString * reason=0 ) const; + void doOperationDoneEvent( const GpgME::Error & e ); + GpgME::Error setup( const std::vector &, const QByteArray & ); private: - static ChiasmusLibrary * self; - mutable KLibrary * mXiaLibrary; + GpgME::SigningResult mResult; }; } - -#endif // __KLEO_CHIASMUSLIBRARY_H__ +#endif // __KLEO_QGPGMESIGNJOB_H__ diff --git a/lib/backends/qgpgme/qgpgmeverifydetachedjob.cpp b/lib/backends/qgpgme/qgpgmeverifydetachedjob.cpp new file mode 100644 index 000000000..1adf12bc2 --- /dev/null +++ b/lib/backends/qgpgme/qgpgmeverifydetachedjob.cpp @@ -0,0 +1,94 @@ +/* + qgpgmeverifydetachedjob.cpp + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "qgpgmeverifydetachedjob.h" + +#include +#include + +#include +#include +#include + +#include + +Kleo::QGpgMEVerifyDetachedJob::QGpgMEVerifyDetachedJob( GpgME::Context * context ) + : VerifyDetachedJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMEVerifyDetachedJob" ), + QGpgMEJob( this, context ) +{ + assert( context ); +} + +Kleo::QGpgMEVerifyDetachedJob::~QGpgMEVerifyDetachedJob() { +} + +void Kleo::QGpgMEVerifyDetachedJob::setup( const QByteArray & signature, const QByteArray & signedData ) { + assert( !mInData ); + assert( !mOutData ); + + createInData( signature ); + + // two "in" data objects - (mis|re)use the "out" data object for the second... + mOutDataDataProvider = new QGpgME::QByteArrayDataProvider( signedData ); + mOutData = new GpgME::Data( mOutDataDataProvider ); + assert( !mOutData->isNull() ); +} + +GpgME::Error Kleo::QGpgMEVerifyDetachedJob::start( const QByteArray & signature, + const QByteArray & signedData ) { + setup( signature, signedData ); + + hookupContextToEventLoopInteractor(); + + const GpgME::Error err = mCtx->startDetachedSignatureVerification( *mInData, *mOutData ); + + if ( err ) + deleteLater(); + return err; +} + +GpgME::VerificationResult Kleo::QGpgMEVerifyDetachedJob::exec( const QByteArray & signature, + const QByteArray & signedData ) { + setup( signature, signedData ); + return mCtx->verifyDetachedSignature( *mInData, *mOutData ); +} + +void Kleo::QGpgMEVerifyDetachedJob::doOperationDoneEvent( const GpgME::Error & ) { + emit result( mCtx->verificationResult() ); +} + + +#include "qgpgmeverifydetachedjob.moc" diff --git a/lib/backends/chiasmus/chiasmuslibrary.h b/lib/backends/qgpgme/qgpgmeverifydetachedjob.h similarity index 55% copy from lib/backends/chiasmus/chiasmuslibrary.h copy to lib/backends/qgpgme/qgpgmeverifydetachedjob.h index 1759b4fc7..76141fb80 100644 --- a/lib/backends/chiasmus/chiasmuslibrary.h +++ b/lib/backends/qgpgme/qgpgmeverifydetachedjob.h @@ -1,68 +1,75 @@ -/* -*- mode: C++; c-file-style: "gnu" -*- - chiasmuslibrary.h +/* + qgpgmeverifydetachedjob.h This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ +#ifndef __KLEO_QGPGMEVERIFYDETACHEDJOB_H__ +#define __KLEO_QGPGMEVERIFYDETACHEDJOB_H__ -#ifndef __KLEO_CHIASMUSLIBRARY_H__ -#define __KLEO_CHIASMUSLIBRARY_H__ +#include + +#include "qgpgmejob.h" -#include #include -class KLibrary; +namespace GpgME { + class Error; + class Context; +} namespace Kleo { - /** - @short small helper class to load xia.o through xia.so and make - the functionality available. - */ - class ChiasmusLibrary { - ChiasmusLibrary(); - ~ChiasmusLibrary(); + class QGpgMEVerifyDetachedJob : public VerifyDetachedJob, private QGpgMEJob { + Q_OBJECT QGPGME_JOB public: - static const ChiasmusLibrary * instance(); - static void deleteInstance(); + QGpgMEVerifyDetachedJob( GpgME::Context * context ); + ~QGpgMEVerifyDetachedJob(); - int perform( const QValueVector & args ) const; - private: - typedef int ( *main_func )( int, char** ); - main_func chiasmus( QString * reason=0 ) const; + /*! \reimp from VerifyDetachedJob */ + GpgME::Error start( const QByteArray & signature, + const QByteArray & signedData ); + + /*! \reimp from VerifyDetachedJob */ + GpgME::VerificationResult exec( const QByteArray & signature, + const QByteArray & signedData ); + + private slots: + void slotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e ) { + QGpgMEJob::doSlotOperationDoneEvent( context, e ); + } private: - static ChiasmusLibrary * self; - mutable KLibrary * mXiaLibrary; + void doOperationDoneEvent( const GpgME::Error & e ); + void setup( const QByteArray &, const QByteArray & ); }; } - -#endif // __KLEO_CHIASMUSLIBRARY_H__ +#endif // __KLEO_QGPGMEVERIFYDETACHEDJOB_H__ diff --git a/lib/backends/qgpgme/qgpgmeverifyopaquejob.cpp b/lib/backends/qgpgme/qgpgmeverifyopaquejob.cpp new file mode 100644 index 000000000..374206bb6 --- /dev/null +++ b/lib/backends/qgpgme/qgpgmeverifyopaquejob.cpp @@ -0,0 +1,90 @@ +/* + qgpgmeverifyopaquejob.cpp + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "qgpgmeverifyopaquejob.h" + +#include +#include + +#include +#include +#include + +#include + +Kleo::QGpgMEVerifyOpaqueJob::QGpgMEVerifyOpaqueJob( GpgME::Context * context ) + : VerifyOpaqueJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMEVerifyOpaqueJob" ), + QGpgMEJob( this, context ) +{ + assert( context ); +} + +Kleo::QGpgMEVerifyOpaqueJob::~QGpgMEVerifyOpaqueJob() { +} + +void Kleo::QGpgMEVerifyOpaqueJob::setup( const QByteArray & signedData ) { + assert( !mInData ); + assert( !mOutData ); + + createInData( signedData ); + createOutData(); +} + +GpgME::Error Kleo::QGpgMEVerifyOpaqueJob::start( const QByteArray & signedData ) { + setup( signedData ); + + hookupContextToEventLoopInteractor(); + + const GpgME::Error err = mCtx->startOpaqueSignatureVerification( *mInData, *mOutData ); + + if ( err ) + deleteLater(); + return err; +} + +GpgME::VerificationResult Kleo::QGpgMEVerifyOpaqueJob::exec( const QByteArray & signedData, QByteArray & plainText ) { + setup( signedData ); + const GpgME::VerificationResult res = mCtx->verifyOpaqueSignature( *mInData, *mOutData ); + plainText = mOutDataDataProvider->data(); + return res; +} + +void Kleo::QGpgMEVerifyOpaqueJob::doOperationDoneEvent( const GpgME::Error & ) { + emit result( mCtx->verificationResult(), mOutDataDataProvider->data() ); +} + + +#include "qgpgmeverifyopaquejob.moc" diff --git a/lib/backends/chiasmus/chiasmuslibrary.h b/lib/backends/qgpgme/qgpgmeverifyopaquejob.h similarity index 57% copy from lib/backends/chiasmus/chiasmuslibrary.h copy to lib/backends/qgpgme/qgpgmeverifyopaquejob.h index 1759b4fc7..2c167fb1d 100644 --- a/lib/backends/chiasmus/chiasmuslibrary.h +++ b/lib/backends/qgpgme/qgpgmeverifyopaquejob.h @@ -1,68 +1,73 @@ -/* -*- mode: C++; c-file-style: "gnu" -*- - chiasmuslibrary.h +/* + qgpgmeverifyopaquejob.h This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ +#ifndef __KLEO_QGPGMEVERIFYOPAQUEJOB_H__ +#define __KLEO_QGPGMEVERIFYOPAQUEJOB_H__ -#ifndef __KLEO_CHIASMUSLIBRARY_H__ -#define __KLEO_CHIASMUSLIBRARY_H__ +#include + +#include "qgpgmejob.h" -#include #include -class KLibrary; +namespace GpgME { + class Error; + class Context; +} namespace Kleo { - /** - @short small helper class to load xia.o through xia.so and make - the functionality available. - */ - class ChiasmusLibrary { - ChiasmusLibrary(); - ~ChiasmusLibrary(); + class QGpgMEVerifyOpaqueJob : public VerifyOpaqueJob, private QGpgMEJob { + Q_OBJECT QGPGME_JOB public: - static const ChiasmusLibrary * instance(); - static void deleteInstance(); + QGpgMEVerifyOpaqueJob( GpgME::Context * context ); + ~QGpgMEVerifyOpaqueJob(); - int perform( const QValueVector & args ) const; - private: - typedef int ( *main_func )( int, char** ); - main_func chiasmus( QString * reason=0 ) const; + /*! \reimp from VerifyOpaqueJob */ + GpgME::Error start( const QByteArray & signedData ); + + /*! \reimp form VerifyOpaqueJob */ + GpgME::VerificationResult exec( const QByteArray & signedData, QByteArray & plainData ); + + private slots: + void slotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e ) { + QGpgMEJob::doSlotOperationDoneEvent( context, e ); + } private: - static ChiasmusLibrary * self; - mutable KLibrary * mXiaLibrary; + void doOperationDoneEvent( const GpgME::Error & e ); + void setup( const QByteArray & ); }; } - -#endif // __KLEO_CHIASMUSLIBRARY_H__ +#endif // __KLEO_QGPGMEVERIFYOPAQUEJOB_H__ diff --git a/lib/cryptplug.cpp b/lib/cryptplug.cpp index cb2478813..7a58cbe04 100644 --- a/lib/cryptplug.cpp +++ b/lib/cryptplug.cpp @@ -1,1123 +1,1123 @@ /* -*- Mode: C++ -*- this is a C++-ification of: GPGMEPLUG - an GPGME based cryptography plug-in following the common CRYPTPLUG specification. Copyright (C) 2001 by Klarälvdalens Datakonsult AB Copyright (C) 2002 g10 Code GmbH Copyright (C) 2004 Klarälvdalens Datakonsult AB GPGMEPLUG is free software; you can redistribute it and/or modify it under the terms of GNU General Public License as published by the Free Software Foundation; version 2 of the License. GPGMEPLUG is distributed in the hope that it will be useful, it under the terms of GNU General Public License as published by the Free Software Foundation; version 2 of the License but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifdef HAVE_CONFIG_H #include #endif #include "kleo/oidmap.h" #include #include #include /*! \file gpgmeplug.c \brief GPGME implementation of CRYPTPLUG following the specification located in common API header cryptplug.h. CRYPTPLUG is an independent cryptography plug-in API developed for Sphinx-enabeling KMail and Mutt. CRYPTPLUG was designed for the Aegypten project, but it may be used by 3rd party developers as well to design pluggable crypto backends for the above mentioned MUAs. \note All string parameters appearing in this API are to be interpreted as UTF-8 encoded. \see cryptplug.h */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define __GPGMEPLUG_ERROR_CLEARTEXT_IS_ZERO "Error: Cannot run checkMessageSignature() with cleartext == 0" /* Note: The following specification will result in function encryptAndSignMessage() producing _empty_ mails. This must be changed as soon as our plugin is supporting the encryptAndSignMessage() function. */ #ifndef GPGMEPLUG_ENCSIGN_MAKE_MIME_OBJECT #define GPGMEPLUG_ENCSIGN_INCLUDE_CLEARTEXT false #define GPGMEPLUG_ENCSIGN_MAKE_MIME_OBJECT false #define GPGMEPLUG_ENCSIGN_MAKE_MULTI_MIME false #define GPGMEPLUG_ENCSIGN_CTYPE_MAIN "" #define GPGMEPLUG_ENCSIGN_CDISP_MAIN "" #define GPGMEPLUG_ENCSIGN_CTENC_MAIN "" #define GPGMEPLUG_ENCSIGN_CTYPE_VERSION "" #define GPGMEPLUG_ENCSIGN_CDISP_VERSION "" #define GPGMEPLUG_ENCSIGN_CTENC_VERSION "" #define GPGMEPLUG_ENCSIGN_BTEXT_VERSION "" #define GPGMEPLUG_ENCSIGN_CTYPE_CODE "" #define GPGMEPLUG_ENCSIGN_CDISP_CODE "" #define GPGMEPLUG_ENCSIGN_CTENC_CODE "" #define GPGMEPLUG_ENCSIGN_FLAT_PREFIX "" #define GPGMEPLUG_ENCSIGN_FLAT_SEPARATOR "" #define GPGMEPLUG_ENCSIGN_FLAT_POSTFIX "" #endif #include "cryptplug.h" #include SMIMECryptPlug::SMIMECryptPlug() : CryptPlug() { GPGMEPLUG_PROTOCOL = GPGME_PROTOCOL_CMS; mProtocol = GpgME::Context::CMS; /* definitions for signing */ // 1. opaque signatures (only used for S/MIME) GPGMEPLUG_OPA_SIGN_INCLUDE_CLEARTEXT = false; GPGMEPLUG_OPA_SIGN_MAKE_MIME_OBJECT = true; GPGMEPLUG_OPA_SIGN_MAKE_MULTI_MIME = false; GPGMEPLUG_OPA_SIGN_CTYPE_MAIN = "application/pkcs7-mime; smime-type=signed-data; name=\"smime.p7m\""; GPGMEPLUG_OPA_SIGN_CDISP_MAIN = "attachment; filename=\"smime.p7m\""; GPGMEPLUG_OPA_SIGN_CTENC_MAIN = "base64"; GPGMEPLUG_OPA_SIGN_CTYPE_VERSION = ""; GPGMEPLUG_OPA_SIGN_CDISP_VERSION = ""; GPGMEPLUG_OPA_SIGN_CTENC_VERSION = ""; GPGMEPLUG_OPA_SIGN_BTEXT_VERSION = ""; GPGMEPLUG_OPA_SIGN_CTYPE_CODE = ""; GPGMEPLUG_OPA_SIGN_CDISP_CODE = ""; GPGMEPLUG_OPA_SIGN_CTENC_CODE = ""; GPGMEPLUG_OPA_SIGN_FLAT_PREFIX = ""; GPGMEPLUG_OPA_SIGN_FLAT_SEPARATOR = ""; GPGMEPLUG_OPA_SIGN_FLAT_POSTFIX = ""; // 2. detached signatures (used for S/MIME and for OpenPGP) GPGMEPLUG_DET_SIGN_INCLUDE_CLEARTEXT = true; GPGMEPLUG_DET_SIGN_MAKE_MIME_OBJECT = true; GPGMEPLUG_DET_SIGN_MAKE_MULTI_MIME = true; GPGMEPLUG_DET_SIGN_CTYPE_MAIN = "multipart/signed; protocol=\"application/pkcs7-signature\"; micalg=sha1"; GPGMEPLUG_DET_SIGN_CDISP_MAIN = ""; GPGMEPLUG_DET_SIGN_CTENC_MAIN = ""; GPGMEPLUG_DET_SIGN_CTYPE_VERSION = ""; GPGMEPLUG_DET_SIGN_CDISP_VERSION = ""; GPGMEPLUG_DET_SIGN_CTENC_VERSION = ""; GPGMEPLUG_DET_SIGN_BTEXT_VERSION = ""; GPGMEPLUG_DET_SIGN_CTYPE_CODE = "application/pkcs7-signature; name=\"smime.p7s\""; GPGMEPLUG_DET_SIGN_CDISP_CODE = "attachment; filename=\"smime.p7s\""; GPGMEPLUG_DET_SIGN_CTENC_CODE = "base64"; GPGMEPLUG_DET_SIGN_FLAT_PREFIX = ""; GPGMEPLUG_DET_SIGN_FLAT_SEPARATOR = ""; GPGMEPLUG_DET_SIGN_FLAT_POSTFIX = ""; // 3. common definitions for opaque and detached signing __GPGMEPLUG_SIGNATURE_CODE_IS_BINARY = true; /* definitions for encoding */ GPGMEPLUG_ENC_INCLUDE_CLEARTEXT = false; GPGMEPLUG_ENC_MAKE_MIME_OBJECT = true; GPGMEPLUG_ENC_MAKE_MULTI_MIME = false; GPGMEPLUG_ENC_CTYPE_MAIN = "application/pkcs7-mime; smime-type=enveloped-data; name=\"smime.p7m\""; GPGMEPLUG_ENC_CDISP_MAIN = "attachment; filename=\"smime.p7m\""; GPGMEPLUG_ENC_CTENC_MAIN = "base64"; GPGMEPLUG_ENC_CTYPE_VERSION = ""; GPGMEPLUG_ENC_CDISP_VERSION = ""; GPGMEPLUG_ENC_CTENC_VERSION = ""; GPGMEPLUG_ENC_BTEXT_VERSION = ""; GPGMEPLUG_ENC_CTYPE_CODE = ""; GPGMEPLUG_ENC_CDISP_CODE = ""; GPGMEPLUG_ENC_CTENC_CODE = ""; GPGMEPLUG_ENC_FLAT_PREFIX = ""; GPGMEPLUG_ENC_FLAT_SEPARATOR = ""; GPGMEPLUG_ENC_FLAT_POSTFIX = ""; __GPGMEPLUG_ENCRYPTED_CODE_IS_BINARY = true; } OpenPGPCryptPlug::OpenPGPCryptPlug() : CryptPlug() { GPGMEPLUG_PROTOCOL = GPGME_PROTOCOL_OpenPGP; mProtocol = GpgME::Context::OpenPGP; /* definitions for signing */ // 1. opaque signatures (only used for S/MIME) GPGMEPLUG_OPA_SIGN_INCLUDE_CLEARTEXT = false; GPGMEPLUG_OPA_SIGN_MAKE_MIME_OBJECT = false; GPGMEPLUG_OPA_SIGN_MAKE_MULTI_MIME = false; GPGMEPLUG_OPA_SIGN_CTYPE_MAIN = ""; GPGMEPLUG_OPA_SIGN_CDISP_MAIN = ""; GPGMEPLUG_OPA_SIGN_CTENC_MAIN = ""; GPGMEPLUG_OPA_SIGN_CTYPE_VERSION = ""; GPGMEPLUG_OPA_SIGN_CDISP_VERSION = ""; GPGMEPLUG_OPA_SIGN_CTENC_VERSION = ""; GPGMEPLUG_OPA_SIGN_BTEXT_VERSION = ""; GPGMEPLUG_OPA_SIGN_CTYPE_CODE = ""; GPGMEPLUG_OPA_SIGN_CDISP_CODE = ""; GPGMEPLUG_OPA_SIGN_CTENC_CODE = ""; GPGMEPLUG_OPA_SIGN_FLAT_PREFIX = ""; GPGMEPLUG_OPA_SIGN_FLAT_SEPARATOR = ""; GPGMEPLUG_OPA_SIGN_FLAT_POSTFIX = ""; // 2. detached signatures (used for S/MIME and for OpenPGP) GPGMEPLUG_DET_SIGN_INCLUDE_CLEARTEXT = true; GPGMEPLUG_DET_SIGN_MAKE_MIME_OBJECT = true; GPGMEPLUG_DET_SIGN_MAKE_MULTI_MIME = true; GPGMEPLUG_DET_SIGN_CTYPE_MAIN = "multipart/signed; protocol=\"application/pgp-signature\"; micalg=pgp-sha1"; GPGMEPLUG_DET_SIGN_CDISP_MAIN = ""; GPGMEPLUG_DET_SIGN_CTENC_MAIN = ""; GPGMEPLUG_DET_SIGN_CTYPE_VERSION = ""; GPGMEPLUG_DET_SIGN_CDISP_VERSION = ""; GPGMEPLUG_DET_SIGN_CTENC_VERSION = ""; GPGMEPLUG_DET_SIGN_BTEXT_VERSION = ""; GPGMEPLUG_DET_SIGN_CTYPE_CODE = "application/pgp-signature"; GPGMEPLUG_DET_SIGN_CDISP_CODE = ""; GPGMEPLUG_DET_SIGN_CTENC_CODE = ""; GPGMEPLUG_DET_SIGN_FLAT_PREFIX = ""; GPGMEPLUG_DET_SIGN_FLAT_SEPARATOR = ""; GPGMEPLUG_DET_SIGN_FLAT_POSTFIX = ""; // 3. common definitions for opaque and detached signing __GPGMEPLUG_SIGNATURE_CODE_IS_BINARY = false; /* definitions for encoding */ GPGMEPLUG_ENC_INCLUDE_CLEARTEXT = false; GPGMEPLUG_ENC_MAKE_MIME_OBJECT = true; GPGMEPLUG_ENC_MAKE_MULTI_MIME = true; GPGMEPLUG_ENC_CTYPE_MAIN = "multipart/encrypted; protocol=\"application/pgp-encrypted\""; GPGMEPLUG_ENC_CDISP_MAIN = ""; GPGMEPLUG_ENC_CTENC_MAIN = ""; GPGMEPLUG_ENC_CTYPE_VERSION = "application/pgp-encrypted"; GPGMEPLUG_ENC_CDISP_VERSION = "attachment"; GPGMEPLUG_ENC_CTENC_VERSION = ""; GPGMEPLUG_ENC_BTEXT_VERSION = "Version: 1"; GPGMEPLUG_ENC_CTYPE_CODE = "application/octet-stream"; GPGMEPLUG_ENC_CDISP_CODE = "inline; filename=\"msg.asc\""; GPGMEPLUG_ENC_CTENC_CODE = ""; GPGMEPLUG_ENC_FLAT_PREFIX = ""; GPGMEPLUG_ENC_FLAT_SEPARATOR = ""; GPGMEPLUG_ENC_FLAT_POSTFIX = ""; __GPGMEPLUG_ENCRYPTED_CODE_IS_BINARY = false; } #define days_from_seconds(x) ((x)/86400) /* Max number of parts in a DN */ #define MAX_GPGME_IDX 20 /* some macros to replace ctype ones and avoid locale problems */ #define spacep(p) (*(p) == ' ' || *(p) == '\t') #define digitp(p) (*(p) >= '0' && *(p) <= '9') #define hexdigitp(a) (digitp (a) \ || (*(a) >= 'A' && *(a) <= 'F') \ || (*(a) >= 'a' && *(a) <= 'f')) /* the atoi macros assume that the buffer has only valid digits */ #define atoi_1(p) (*(p) - '0' ) #define atoi_2(p) ((atoi_1(p) * 10) + atoi_1((p)+1)) #define atoi_4(p) ((atoi_2(p) * 100) + atoi_2((p)+2)) #define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) #define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) static void * xmalloc (size_t n) { void *p = malloc (n); if (!p) { fputs ("\nfatal: out of core\n", stderr); exit (4); } return p; } /* Please: Don't call an allocation function xfoo when it may return NULL. */ /* Wrong: #define xstrdup( x ) (x)?strdup(x):0 */ /* Right: */ static char * xstrdup (const char *string) { char *p = (char*)xmalloc (strlen (string)+1); strcpy (p, string); return p; } CryptPlug::CryptPlug() { } CryptPlug::~CryptPlug() { } bool CryptPlug::initialize() { GpgME::setDefaultLocale( LC_CTYPE, setlocale( LC_CTYPE, 0 ) ); GpgME::setDefaultLocale( LC_MESSAGES, setlocale( LC_MESSAGES, 0 ) ); return (gpgme_engine_check_version (GPGMEPLUG_PROTOCOL) == GPG_ERR_NO_ERROR); } bool CryptPlug::hasFeature( Feature flag ) { /* our own plugins are supposed to support everything */ switch ( flag ) { case Feature_SignMessages: case Feature_VerifySignatures: case Feature_EncryptMessages: case Feature_DecryptMessages: case Feature_SendCertificates: case Feature_PinEntrySettings: case Feature_StoreMessagesWithSigs: case Feature_EncryptionCRLs: case Feature_StoreMessagesEncrypted: case Feature_CheckCertificatePath: return true; case Feature_WarnSignCertificateExpiry: case Feature_WarnSignEmailNotInCertificate: case Feature_WarnEncryptCertificateExpiry: case Feature_WarnEncryptEmailNotInCertificate: return GPGMEPLUG_PROTOCOL == GPGME_PROTOCOL_CMS; /* undefined or not yet implemented: */ case Feature_CRLDirectoryService: case Feature_CertificateDirectoryService: case Feature_undef: default: return false; } } static void storeNewCharPtr( char** dest, const char* src ) { int sLen = strlen( src ); *dest = (char*)xmalloc( sLen + 1 ); strcpy( *dest, src ); } bool CryptPlug::decryptMessage( const char* ciphertext, bool cipherIsBinary, int cipherLen, const char** cleartext, const char* /*certificate*/, int* errId, char** errTxt ) { gpgme_ctx_t ctx; gpgme_error_t err; gpgme_data_t gCiphertext, gPlaintext; size_t rCLen = 0; char* rCiph = 0; bool bOk = false; if( !ciphertext ) return false; err = gpgme_new (&ctx); gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL); gpgme_set_armor (ctx, cipherIsBinary ? 0 : 1); /* gpgme_set_textmode (ctx, cipherIsBinary ? 0 : 1); */ /* gpgme_data_new_from_mem( &gCiphertext, ciphertext, 1+strlen( ciphertext ), 1 ); */ gpgme_data_new_from_mem( &gCiphertext, ciphertext, cipherIsBinary ? cipherLen : strlen( ciphertext ), 1 ); gpgme_data_new( &gPlaintext ); err = gpgme_op_decrypt( ctx, gCiphertext, gPlaintext ); if( err ) { fprintf( stderr, "\ngpgme_op_decrypt() returned this error code: %i\n\n", err ); if( errId ) *errId = err; if( errTxt ) { const char* _errTxt = gpgme_strerror( err ); *errTxt = (char*)malloc( strlen( _errTxt ) + 1 ); if( *errTxt ) strcpy(*errTxt, _errTxt ); } } gpgme_data_release( gCiphertext ); rCiph = gpgme_data_release_and_get_mem( gPlaintext, &rCLen ); *cleartext = (char*)malloc( rCLen + 1 ); if( *cleartext ) { if( rCLen ) { bOk = true; strncpy((char*)*cleartext, rCiph, rCLen ); } ((char*)(*cleartext))[rCLen] = 0; } free( rCiph ); gpgme_release( ctx ); return bOk; } static char * trim_trailing_spaces( char *string ) { char *p, *mark; for( mark = NULL, p = string; *p; p++ ) { if( isspace( *p ) ) { if( !mark ) mark = p; } else mark = NULL; } if( mark ) *mark = '\0' ; return string ; } /* Parse a DN and return an array-ized one. This is not a validating parser and it does not support any old-stylish syntax; gpgme is expected to return only rfc2253 compatible strings. */ static const unsigned char * parse_dn_part (CryptPlug::DnPair *array, const unsigned char *string) { const unsigned char *s, *s1; size_t n; char *p; /* parse attributeType */ for (s = string+1; *s && *s != '='; s++) ; if (!*s) return NULL; /* error */ n = s - string; if (!n) return NULL; /* empty key */ p = (char*)xmalloc (n+1); memcpy (p, string, n); p[n] = 0; trim_trailing_spaces ((char*)p); // map OIDs to their names: for ( unsigned int i = 0 ; i < numOidMaps ; ++i ) if ( !strcasecmp ((char*)p, oidmap[i].oid) ) { free( p ); p = xstrdup (oidmap[i].name); break; } array->key = p; string = s + 1; if (*string == '#') { /* hexstring */ string++; for (s=string; hexdigitp (s); s++) s++; n = s - string; if (!n || (n & 1)) return NULL; /* empty or odd number of digits */ n /= 2; array->value = p = (char*)xmalloc (n+1); for (s1=string; n; s1 += 2, n--) *p++ = xtoi_2 (s1); *p = 0; } else { /* regular v3 quoted string */ for (n=0, s=string; *s; s++) { if (*s == '\\') { /* pair */ s++; if (*s == ',' || *s == '=' || *s == '+' || *s == '<' || *s == '>' || *s == '#' || *s == ';' || *s == '\\' || *s == '\"' || *s == ' ') n++; else if (hexdigitp (s) && hexdigitp (s+1)) { s++; n++; } else return NULL; /* invalid escape sequence */ } else if (*s == '\"') return NULL; /* invalid encoding */ else if (*s == ',' || *s == '=' || *s == '+' || *s == '<' || *s == '>' || *s == '#' || *s == ';' ) break; else n++; } array->value = p = (char*)xmalloc (n+1); for (s=string; n; s++, n--) { if (*s == '\\') { s++; if (hexdigitp (s)) { *p++ = xtoi_2 (s); s++; } else *p++ = *s; } else *p++ = *s; } *p = 0; } return s; } /* Parse a DN and return an array-ized one. This is not a validating parser and it does not support any old-stylish syntax; gpgme is expected to return only rfc2253 compatible strings. */ static CryptPlug::DnPair * parse_dn (const unsigned char *string) { struct CryptPlug::DnPair *array; size_t arrayidx, arraysize; if( !string ) return NULL; arraysize = 7; /* C,ST,L,O,OU,CN,email */ arrayidx = 0; array = (CryptPlug::DnPair*)xmalloc ((arraysize+1) * sizeof *array); while (*string) { while (*string == ' ') string++; if (!*string) break; /* ready */ if (arrayidx >= arraysize) { /* mutt lacks a real safe_realoc - so we need to copy */ struct CryptPlug::DnPair *a2; arraysize += 5; a2 = (CryptPlug::DnPair*)xmalloc ((arraysize+1) * sizeof *array); for (unsigned int i=0; i < arrayidx; i++) { a2[i].key = array[i].key; a2[i].value = array[i].value; } free (array); array = a2; } array[arrayidx].key = NULL; array[arrayidx].value = NULL; string = parse_dn_part (array+arrayidx, string); arrayidx++; if (!string) goto failure; while (*string == ' ') string++; if (*string && *string != ',' && *string != ';' && *string != '+') goto failure; /* invalid delimiter */ if (*string) string++; } array[arrayidx].key = NULL; array[arrayidx].value = NULL; return array; failure: for (unsigned i=0; i < arrayidx; i++) { free (array[i].key); free (array[i].value); } free (array); return NULL; } static void add_dn_part( QCString& result, struct CryptPlug::DnPair& dnPair ) { /* email hack */ QCString mappedPart( dnPair.key ); for ( unsigned int i = 0 ; i < numOidMaps ; ++i ){ if( !strcasecmp( dnPair.key, oidmap[i].oid ) ) { mappedPart = oidmap[i].name; break; } } result.append( mappedPart ); result.append( "=" ); result.append( dnPair.value ); } static int add_dn_parts( QCString& result, struct CryptPlug::DnPair* dn, const char* part ) { int any = 0; if( dn ) { for(; dn->key; ++dn ) { if( !strcmp( dn->key, part ) ) { if( any ) result.append( "," ); add_dn_part( result, *dn ); any = 1; } } } return any; } static char* reorder_dn( struct CryptPlug::DnPair *dn, char** attrOrder = 0, const char* unknownAttrsHandling = 0 ) { struct CryptPlug::DnPair *dnOrg = dn; /* note: The must parts are: CN, L, OU, O, C */ const char* defaultpart[] = { "CN", "S", "SN", "GN", "T", "UID", "MAIL", "EMAIL", "MOBILE", "TEL", "FAX", "STREET", "L", "PC", "SP", "ST", "OU", "O", "C", NULL }; const char** stdpart = attrOrder ? ((const char**)attrOrder) : defaultpart; int any=0, any2=0, found_X_=0, i; QCString result; QCString resultUnknowns; /* find and save the non-standard parts in their original order */ if( dn ){ for(; dn->key; ++dn ) { for( i = 0; stdpart[i]; ++i ) { if( !strcmp( dn->key, stdpart[i] ) ) { break; } } if( !stdpart[i] ) { if( any2 ) resultUnknowns.append( "," ); add_dn_part( resultUnknowns, *dn ); any2 = 1; } } dn = dnOrg; } /* prepend the unknown attrs if desired */ if( unknownAttrsHandling && !strcmp(unknownAttrsHandling, "PREFIX") && *resultUnknowns ){ result.append( resultUnknowns ); any = 1; }else{ any = 0; } /* add standard parts */ for( i = 0; stdpart[i]; ++i ) { dn = dnOrg; if( any ) { result.append( "," ); } if( any2 && !strcmp(stdpart[i], "_X_") && unknownAttrsHandling && !strcmp(unknownAttrsHandling, "INFIX") ){ if ( !resultUnknowns.isEmpty() ) { result.append( resultUnknowns ); any = 1; } found_X_ = 1; }else{ any = add_dn_parts( result, dn, stdpart[i] ); } } /* append the unknown attrs if desired */ if( !unknownAttrsHandling || !strcmp(unknownAttrsHandling, "POSTFIX") || ( !strcmp(unknownAttrsHandling, "INFIX") && !found_X_ ) ){ if( !resultUnknowns.isEmpty() ) { if( any ){ result.append( "," ); } result.append( resultUnknowns ); } } char* cResult = (char*)xmalloc( (result.length()+1)*sizeof(char) ); if( result.isEmpty() ) *cResult = 0; else strcpy( cResult, result ); return cResult; } GpgME::ImportResult CryptPlug::importCertificateFromMem( const char* data, size_t length ) { using namespace GpgME; std::auto_ptr context( Context::createForProtocol( mProtocol ) ); if ( !context.get() ) return ImportResult(); Data keydata( data, length, false ); if ( keydata.isNull() ) return ImportResult(); return context->importKeys( keydata ); } /* == == == == == == == == == == == == == == == == == == == == == == == == == == == == Continuation of CryptPlug code == == == == == == == == == == == == == == == == == == == == == == == == == == == == */ // these are from gpgme-0.4.3: static gpgme_sig_stat_t sig_stat_from_status( gpgme_error_t err ) { switch ( gpg_err_code(err) ) { case GPG_ERR_NO_ERROR: return GPGME_SIG_STAT_GOOD; case GPG_ERR_BAD_SIGNATURE: return GPGME_SIG_STAT_BAD; case GPG_ERR_NO_PUBKEY: return GPGME_SIG_STAT_NOKEY; case GPG_ERR_NO_DATA: return GPGME_SIG_STAT_NOSIG; case GPG_ERR_SIG_EXPIRED: return GPGME_SIG_STAT_GOOD_EXP; case GPG_ERR_KEY_EXPIRED: return GPGME_SIG_STAT_GOOD_EXPKEY; default: return GPGME_SIG_STAT_ERROR; } } static gpgme_sig_stat_t intersect_stati( gpgme_signature_t first ) { if ( !first ) return GPGME_SIG_STAT_NONE; gpgme_sig_stat_t result = sig_stat_from_status( first->status ); for ( gpgme_signature_t sig = first->next ; sig ; sig = sig->next ) if ( sig_stat_from_status( sig->status ) != result ) return GPGME_SIG_STAT_DIFF; return result; } static const char* sig_status_to_string( gpgme_sig_stat_t status ) { const char *result; switch (status) { case GPGME_SIG_STAT_NONE: result = "Oops: Signature not verified"; break; case GPGME_SIG_STAT_NOSIG: result = "No signature found"; break; case GPGME_SIG_STAT_GOOD: result = "Good signature"; break; case GPGME_SIG_STAT_BAD: result = "BAD signature"; break; case GPGME_SIG_STAT_NOKEY: result = "No public key to verify the signature"; break; case GPGME_SIG_STAT_ERROR: result = "Error verifying the signature"; break; case GPGME_SIG_STAT_DIFF: result = "Different results for signatures"; break; default: result = "Error: Unknown status"; break; } return result; } // WARNING: if you fix a bug here, you have to likely fix it in the // gpgme 0.3 version below, too! static void obtain_signature_information( gpgme_ctx_t ctx, gpgme_sig_stat_t & overallStatus, struct CryptPlug::SignatureMetaData* sigmeta, char** attrOrder, const char* unknownAttrsHandling, bool * signatureFound=0 ) { gpgme_error_t err; unsigned long sumGPGME; SigStatusFlags sumPlug; struct CryptPlug::DnPair* a; int sig_idx=0; assert( ctx ); assert( sigmeta ); sigmeta->extended_info = 0; gpgme_verify_result_t result = gpgme_op_verify_result( ctx ); if ( !result ) return; for ( gpgme_signature_t signature = result->signatures ; signature ; signature = signature->next, ++sig_idx ) { void* alloc_return = realloc( sigmeta->extended_info, sizeof( CryptPlug::SignatureMetaDataExtendedInfo ) * ( sig_idx + 1 ) ); if ( !alloc_return ) break; sigmeta->extended_info = (CryptPlug::SignatureMetaDataExtendedInfo*)alloc_return; /* shorthand notation :) */ CryptPlug::SignatureMetaDataExtendedInfo & this_info = sigmeta->extended_info[sig_idx]; /* clear the data area */ memset( &this_info, 0, sizeof (CryptPlug::SignatureMetaDataExtendedInfo) ); /* the creation time */ if ( signature->timestamp ) { this_info.creation_time = (tm*)malloc( sizeof( struct tm ) ); if ( this_info.creation_time ) { struct tm * ctime_val = localtime( (time_t*)&signature->timestamp ); memcpy( this_info.creation_time, ctime_val, sizeof( struct tm ) ); } } /* the extended signature verification status */ sumGPGME = signature->summary; fprintf( stderr, "gpgmeplug checkMessageSignature status flags: %lX\n", sumGPGME ); /* translate GPGME status flags to common CryptPlug status flags */ sumPlug = 0; #define convert(X) if ( sumGPGME & GPGME_SIGSUM_##X ) sumPlug |= SigStat_##X convert(VALID); convert(GREEN); convert(RED); convert(KEY_REVOKED); convert(KEY_EXPIRED); convert(SIG_EXPIRED); convert(KEY_MISSING); convert(CRL_MISSING); convert(CRL_TOO_OLD); convert(BAD_POLICY); convert(SYS_ERROR); #undef convert if( sumGPGME && !sumPlug ) sumPlug = SigStat_NUMERICAL_CODE | sumGPGME; this_info.sigStatusFlags = sumPlug; /* extract finger print */ if ( signature->fpr ) storeNewCharPtr( &this_info.fingerprint, signature->fpr ); /* validity */ this_info.validity = GPGME_VALIDITY_UNKNOWN; /* sig key data */ gpgme_key_t key = 0; // PENDING(marc) if this is deprecated, how shall we get at all // the infos below? err = gpgme_get_sig_key (ctx, sig_idx, &key); if ( !err && key ) { const char* attr_string; unsigned long attr_ulong; /* extract key identidy */ attr_string = key->subkeys ? key->subkeys->keyid : 0 ; if ( attr_string ) storeNewCharPtr( &this_info.keyid, attr_string ); /* pubkey algorithm */ attr_string = key->subkeys ? gpgme_pubkey_algo_name( key->subkeys->pubkey_algo ) : 0 ; if (attr_string != 0) storeNewCharPtr( &this_info.algo, attr_string ); attr_ulong = key->subkeys ? key->subkeys->pubkey_algo : 0 ; this_info.algo_num = attr_ulong; /* extract key validity */ attr_ulong = key->uids ? key->uids->validity : 0 ; this_info.validity = attr_ulong; /* extract user id, according to the documentation it's representable * as a number, but it seems that it also has a string representation */ attr_string = key->uids ? key->uids->uid : 0 ; if (attr_string != 0) { a = parse_dn( (const unsigned char*)attr_string ); this_info.userid = reorder_dn( a, attrOrder, unknownAttrsHandling ); } attr_ulong = 0; this_info.userid_num = attr_ulong; /* extract the length */ this_info.keylen = key->subkeys ? key->subkeys->length : 0 ; /* extract the creation time of the key */ attr_ulong = key->subkeys ? key->subkeys->timestamp : 0 ; this_info.key_created = attr_ulong; /* extract the expiration time of the key */ attr_ulong = key->subkeys ? key->subkeys->expires : 0 ; this_info.key_expires = attr_ulong; /* extract user name */ attr_string = key->uids ? key->uids->name : 0 ; if (attr_string != 0) { a = parse_dn( (const unsigned char*)attr_string ); this_info.name = reorder_dn( a, attrOrder, unknownAttrsHandling ); } /* extract email(s) */ this_info.emailCount = 0; this_info.emailList = 0; for ( gpgme_user_id_t uid = key->uids ; uid ; uid = uid->next ) { attr_string = uid->email; if ( attr_string && *attr_string) { fprintf( stderr, "gpgmeplug checkMessageSignature found email: %s\n", attr_string ); if( !this_info.emailCount ) alloc_return = malloc( sizeof( char*) ); else alloc_return = realloc( this_info.emailList, sizeof( char*) * (this_info.emailCount + 1) ); if( alloc_return ) { this_info.emailList = (char**)alloc_return; storeNewCharPtr( &( this_info.emailList[ this_info.emailCount ] ), attr_string ); ++this_info.emailCount; } } } if( !this_info.emailCount ) fprintf( stderr, "gpgmeplug checkMessageSignature found NO EMAIL\n" ); /* extract the comment */ attr_string = key->uids ? key->uids->comment : 0 ; if (attr_string != 0) storeNewCharPtr( &this_info.comment, attr_string ); } gpgme_sig_stat_t status = sig_stat_from_status( signature->status ); const char* sig_status = sig_status_to_string( status ); storeNewCharPtr( &this_info.status_text, sig_status ); } sigmeta->extended_info_count = sig_idx; overallStatus = intersect_stati( result->signatures ); sigmeta->status_code = overallStatus; storeNewCharPtr( &sigmeta->status, sig_status_to_string( overallStatus ) ); if ( signatureFound ) *signatureFound = ( overallStatus != GPGME_SIG_STAT_NONE ); } bool CryptPlug::checkMessageSignature( char** cleartext, const char* signaturetext, bool signatureIsBinary, int signatureLen, struct CryptPlug::SignatureMetaData* sigmeta, char** attrOrder, const char* unknownAttrsHandling ) { gpgme_ctx_t ctx; gpgme_sig_stat_t status = GPGME_SIG_STAT_NONE; gpgme_data_t datapart, sigpart; char* rClear = 0; size_t clearLen; bool isOpaqueSigned; if( !cleartext ) { if( sigmeta ) storeNewCharPtr( &sigmeta->status, __GPGMEPLUG_ERROR_CLEARTEXT_IS_ZERO ); return false; } isOpaqueSigned = !*cleartext; gpgme_new( &ctx ); gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL); gpgme_set_armor (ctx, signatureIsBinary ? 0 : 1); /* gpgme_set_textmode (ctx, signatureIsBinary ? 0 : 1); */ if( isOpaqueSigned ) gpgme_data_new( &datapart ); else gpgme_data_new_from_mem( &datapart, *cleartext, strlen( *cleartext ), 1 ); gpgme_data_new_from_mem( &sigpart, signaturetext, signatureIsBinary ? signatureLen : strlen( signaturetext ), 1 ); if ( isOpaqueSigned ) gpgme_op_verify( ctx, sigpart, 0, datapart ); else gpgme_op_verify( ctx, sigpart, datapart, 0 ); if( isOpaqueSigned ) { rClear = gpgme_data_release_and_get_mem( datapart, &clearLen ); *cleartext = (char*)malloc( clearLen + 1 ); if( *cleartext ) { if( clearLen ) strncpy(*cleartext, rClear, clearLen ); (*cleartext)[clearLen] = '\0'; } free( rClear ); } else gpgme_data_release( datapart ); gpgme_data_release( sigpart ); obtain_signature_information( ctx, status, sigmeta, attrOrder, unknownAttrsHandling ); gpgme_release( ctx ); return ( status == GPGME_SIG_STAT_GOOD ); } bool CryptPlug::decryptAndCheckMessage( const char* ciphertext, bool cipherIsBinary, int cipherLen, const char** cleartext, const char* /*certificate*/, bool* signatureFound, struct CryptPlug::SignatureMetaData* sigmeta, int* errId, char** errTxt, char** attrOrder, const char* unknownAttrsHandling ) { gpgme_ctx_t ctx; gpgme_error_t err; gpgme_decrypt_result_t decryptresult; gpgme_data_t gCiphertext, gPlaintext; gpgme_sig_stat_t sigstatus = GPGME_SIG_STAT_NONE; size_t rCLen = 0; char* rCiph = 0; bool bOk = false; bool bWrongKeyUsage = false; if( !ciphertext ) return false; err = gpgme_new (&ctx); gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL); gpgme_set_armor (ctx, cipherIsBinary ? 0 : 1); /* gpgme_set_textmode (ctx, cipherIsBinary ? 0 : 1); */ /* gpgme_data_new_from_mem( &gCiphertext, ciphertext, 1+strlen( ciphertext ), 1 ); */ gpgme_data_new_from_mem( &gCiphertext, ciphertext, cipherIsBinary ? cipherLen : strlen( ciphertext ), 1 ); gpgme_data_new( &gPlaintext ); err = gpgme_op_decrypt_verify( ctx, gCiphertext, gPlaintext ); gpgme_data_release( gCiphertext ); decryptresult = gpgme_op_decrypt_result( ctx ); #ifdef HAVE_GPGME_WRONG_KEY_USAGE if( decryptresult->wrong_key_usage ) bWrongKeyUsage = true; #endif if( err ) { fprintf( stderr, "\ngpgme_op_decrypt_verify() returned this error code: %i\n\n", err ); if( errId ) *errId = err; if( errTxt ) { const char* _errTxt = gpgme_strerror( err ); *errTxt = (char*)malloc( strlen( _errTxt ) + 1 ); if( *errTxt ) strcpy(*errTxt, _errTxt ); } gpgme_data_release( gPlaintext ); gpgme_release( ctx ); return bOk; } if( bWrongKeyUsage ) { if( errId ) *errId = CRYPTPLUG_ERR_WRONG_KEY_USAGE; // report the wrong key usage } rCiph = gpgme_data_release_and_get_mem( gPlaintext, &rCLen ); *cleartext = (char*)malloc( rCLen + 1 ); if( *cleartext ) { if( rCLen ) { bOk = true; strncpy((char*)*cleartext, rCiph, rCLen ); } ((char*)(*cleartext))[rCLen] = 0; } free( rCiph ); obtain_signature_information( ctx, sigstatus, sigmeta, attrOrder, unknownAttrsHandling, signatureFound ); gpgme_release( ctx ); return bOk; } diff --git a/lib/cryptplug.h b/lib/cryptplug.h index 8efc5120b..0e3ccb696 100644 --- a/lib/cryptplug.h +++ b/lib/cryptplug.h @@ -1,954 +1,954 @@ /* -*- Mode: C++ -*- this is a C++-ification of: CRYPTPLUG - an independent cryptography plug-in API Copyright (C) 2001,2004 Klarälvdalens Datakonsult AB CRYPTPLUG is free software; you can redistribute it and/or modify it under the terms of GNU General Public License as published by the Free Software Foundation; version 2 of the License. CRYPTPLUG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef CRYPTPLUG_H #define CRYPTPLUG_H #include #include #include // need it for gpgme_protocol_t :( #include namespace GpgME { class ImportResult; } /*! \file cryptplug.h \brief Common API header for CRYPTPLUG. CRYPTPLUG is an independent cryptography plug-in API developed for Sphinx-enabeling KMail and Mutt. CRYPTPLUG was designed for the Aegypten project, but it may be used by 3rd party developers as well to design pluggable crypto backends for the above mentioned MUAs. \note All string parameters appearing in this API are to be interpreted as UTF-8 encoded. \see pgpplugin.c \see gpgplugin.c */ /*! \defgroup groupGeneral Loading and Unloading the Plugin, General Functionality The functions in this section are used for loading and unloading plugins. Note that the actual locating of the plugin and the loading and unloading of the dynamic library is not covered here; this is MUA-specific code for which support code might already exist in the programming environments. */ /*! \defgroup groupDisplay Graphical Display Functionality The functions in this section return stationery that the MUAs can use in order to display security functionality graphically. This can be toolbar icons, shortcuts, tooltips, etc. Not all MUAs will use all this functionality. */ /*! \defgroup groupConfig Configuration Support The functions in this section provide the necessary functionality to configure the security functionality as well as to query configuration settings. Since all configuration settings will not be saved with the plugin, but rather with the MUA, there are also functions to set configuration settings programmatically; these will be used on startup of the plugin when the MUA transfers the configuration values it has read into the plugin. Usually, the functions to query and set the configuration values are not needed for anything but saving to and restoring from configuration files. */ /*! \defgroup groupConfigSign Signature Configuration \ingroup groupConfig The functions in this section provide the functionality to configure signature handling and set and query the signature configuration. */ /*! \defgroup groupConfigCrypt Encryption Configuration \ingroup groupConfig The functions in this section provide the functionality to configure encryption handling and set and query the encryption configuration. \note Whenever the term encryption is used here, it is supposed to mean both encryption and decryption, unless otherwise specified. */ /*! \defgroup groupConfigDir Directory Service Configuration \ingroup groupConfig This section contains messages for configuring the directory service. */ /*! \defgroup groupCertHand Certificate Handling The following methods are used to maintain and query certificates. */ /*! \defgroup groupSignCryptAct Signing and Encrypting Actions This section describes methods and structures used for signing and/or encrypting your mails. */ /*! \defgroup groupSignAct Signature Actions \ingroup groupSignCryptAct This section describes methods that are used for working with signatures. */ /*! \defgroup groupCryptAct Encryption and Decryption \ingroup groupSignCryptAct The following methods are used to encrypt and decrypt email messages. */ /*! \defgroup groupCertAct Certificate Handling Actions The functions in this section provide local certificate management. */ /*! \defgroup groupCRLAct CRL Handling Actions This section describes functions for managing CRLs. */ /*! \defgroup groupAdUsoInterno Important functions to be used by plugin implementors ONLY. This section describes functions that have to be used by plugin implementors but should not be used by plugin users directly. If you are not planning to write your own cryptography plugin you should ignore this section! */ /*! \defgroup certList Certificate Info listing functions */ typedef enum { Feature_undef = 0, Feature_SignMessages = 1, Feature_VerifySignatures = 2, Feature_EncryptMessages = 3, Feature_DecryptMessages = 4, Feature_SendCertificates = 5, Feature_WarnSignCertificateExpiry = 6, Feature_WarnSignEmailNotInCertificate = 7, Feature_PinEntrySettings = 8, Feature_StoreMessagesWithSigs = 9, Feature_EncryptionCRLs = 10, Feature_WarnEncryptCertificateExpiry = 11, Feature_WarnEncryptEmailNotInCertificate = 12, Feature_StoreMessagesEncrypted = 13, Feature_CheckCertificatePath = 14, Feature_CertificateDirectoryService = 15, Feature_CRLDirectoryService = 16, Feature_CertificateInfo = 17 } Feature; /* dummy values */ typedef enum { PinRequest_undef = 0, PinRequest_Always = 1, PinRequest_WhenAddingCerts = 2, PinRequest_AlwaysWhenSigning = 3, PinRequest_OncePerSession = 4, PinRequest_AfterMinutes = 5 } PinRequests; typedef enum { SignatureCompoundMode_undef = 0, SignatureCompoundMode_Opaque = 1, SignatureCompoundMode_Detached = 2 } SignatureCompoundMode; typedef enum { SendCert_undef = 0, SendCert_DontSend = 1, SendCert_SendOwn = 2, SendCert_SendChainWithoutRoot = 3, SendCert_SendChainWithRoot = 4 } SendCertificates; typedef enum { SignAlg_undef = 0, SignAlg_SHA1 = 1 } SignatureAlgorithm; typedef enum { EncryptAlg_undef = 0, EncryptAlg_RSA = 1, EncryptAlg_SHA1 = 2, EncryptAlg_TripleDES = 3 } EncryptionAlgorithm; typedef enum { SignEmail_undef = 0, SignEmail_SignAll = 1, SignEmail_Ask = 2, SignEmail_DontSign = 3 } SignEmail; typedef enum { EncryptEmail_undef = 0, EncryptEmail_EncryptAll = 1, EncryptEmail_Ask = 2, EncryptEmail_DontEncrypt = 3 } EncryptEmail; typedef enum { CertSrc_undef = 0, CertSrc_Server = 1, CertSrc_Local = 2, CertSrc_ServerLocal = CertSrc_Server | CertSrc_Local } CertificateSource; /*! \ingroup groupSignAct \brief Flags used to compose the SigStatusFlags value. This status flags are used to compose the SigStatusFlags value returned in \c SignatureMetaDataExtendedInfo after trying to verify a signed message part's signature status. The normal flags may not be used together with the special SigStat_NUMERICAL_CODE flag. When finding the special SigStat_NUMERICAL_CODE flag in a SigStatusFlags value you can obtain the respective error code number by substracting the SigStatusFlags value by SigStat_NUMERICAL_CODE: this is used to transport special status information NOT matching any of the normal predefined status codes. \note to PlugIn developers: Implementations of the CryptPlug API should try to express their signature states by bit-wise OR'ing the normal SigStatusFlags values. Using the SigStat_NUMERICAL_CODE flag should only be used as for exceptional situations where no other flag(s) could be used. By using the normal status flags your PlugIn's users will be told an understandable description of the status - when using (SigStat_NUMERICAL_CODE + internalCode) they will only be shown the respective code number and have to look into your PlugIn's manual to learn about it's meaning... */ enum { SigStat_VALID = 0x0001, /* The signature is fully valid */ SigStat_GREEN = 0x0002, /* The signature is good. */ SigStat_RED = 0x0004, /* The signature is bad. */ SigStat_KEY_REVOKED = 0x0010, /* One key has been revoked. */ SigStat_KEY_EXPIRED = 0x0020, /* One key has expired. */ SigStat_SIG_EXPIRED = 0x0040, /* The signature has expired. */ SigStat_KEY_MISSING = 0x0080, /* Can't verify: key missing. */ SigStat_CRL_MISSING = 0x0100, /* CRL not available. */ SigStat_CRL_TOO_OLD = 0x0200, /* Available CRL is too old. */ SigStat_BAD_POLICY = 0x0400, /* A policy was not met. */ SigStat_SYS_ERROR = 0x0800, /* A system error occurred. */ SigStat_NUMERICAL_CODE = 0x8000 /* An other error occurred. */ }; typedef unsigned long SigStatusFlags; class CryptPlugWrapper; class KDE_EXPORT CryptPlug { friend class CryptPlugWrapper; protected: CryptPlug(); virtual ~CryptPlug(); // these must be set by subclasses: gpgme_protocol_t GPGMEPLUG_PROTOCOL; GpgME::Context::Protocol mProtocol; /* definitions for signing */ // 1. opaque signatures (only used for S/MIME) int GPGMEPLUG_OPA_SIGN_INCLUDE_CLEARTEXT; int GPGMEPLUG_OPA_SIGN_MAKE_MIME_OBJECT; int GPGMEPLUG_OPA_SIGN_MAKE_MULTI_MIME; const char * GPGMEPLUG_OPA_SIGN_CTYPE_MAIN; const char * GPGMEPLUG_OPA_SIGN_CDISP_MAIN; const char * GPGMEPLUG_OPA_SIGN_CTENC_MAIN; const char * GPGMEPLUG_OPA_SIGN_CTYPE_VERSION; const char * GPGMEPLUG_OPA_SIGN_CDISP_VERSION; const char * GPGMEPLUG_OPA_SIGN_CTENC_VERSION; const char * GPGMEPLUG_OPA_SIGN_BTEXT_VERSION; const char * GPGMEPLUG_OPA_SIGN_CTYPE_CODE; const char * GPGMEPLUG_OPA_SIGN_CDISP_CODE; const char * GPGMEPLUG_OPA_SIGN_CTENC_CODE; const char * GPGMEPLUG_OPA_SIGN_FLAT_PREFIX; const char * GPGMEPLUG_OPA_SIGN_FLAT_SEPARATOR; const char * GPGMEPLUG_OPA_SIGN_FLAT_POSTFIX; // 2. detached signatures (used for S/MIME and for OpenPGP) int GPGMEPLUG_DET_SIGN_INCLUDE_CLEARTEXT; int GPGMEPLUG_DET_SIGN_MAKE_MIME_OBJECT; int GPGMEPLUG_DET_SIGN_MAKE_MULTI_MIME; const char * GPGMEPLUG_DET_SIGN_CTYPE_MAIN; const char * GPGMEPLUG_DET_SIGN_CDISP_MAIN; const char * GPGMEPLUG_DET_SIGN_CTENC_MAIN; const char * GPGMEPLUG_DET_SIGN_CTYPE_VERSION; const char * GPGMEPLUG_DET_SIGN_CDISP_VERSION; const char * GPGMEPLUG_DET_SIGN_CTENC_VERSION; const char * GPGMEPLUG_DET_SIGN_BTEXT_VERSION; const char * GPGMEPLUG_DET_SIGN_CTYPE_CODE; const char * GPGMEPLUG_DET_SIGN_CDISP_CODE; const char * GPGMEPLUG_DET_SIGN_CTENC_CODE; const char * GPGMEPLUG_DET_SIGN_FLAT_PREFIX; const char * GPGMEPLUG_DET_SIGN_FLAT_SEPARATOR; const char * GPGMEPLUG_DET_SIGN_FLAT_POSTFIX; // 3. common definitions for opaque and detached signing int __GPGMEPLUG_SIGNATURE_CODE_IS_BINARY; /* definitions for encoding */ int GPGMEPLUG_ENC_INCLUDE_CLEARTEXT; int GPGMEPLUG_ENC_MAKE_MIME_OBJECT; int GPGMEPLUG_ENC_MAKE_MULTI_MIME; const char * GPGMEPLUG_ENC_CTYPE_MAIN; const char * GPGMEPLUG_ENC_CDISP_MAIN; const char * GPGMEPLUG_ENC_CTENC_MAIN; const char * GPGMEPLUG_ENC_CTYPE_VERSION; const char * GPGMEPLUG_ENC_CDISP_VERSION; const char * GPGMEPLUG_ENC_CTENC_VERSION; const char * GPGMEPLUG_ENC_BTEXT_VERSION; const char * GPGMEPLUG_ENC_CTYPE_CODE; const char * GPGMEPLUG_ENC_CDISP_CODE; const char * GPGMEPLUG_ENC_CTENC_CODE; const char * GPGMEPLUG_ENC_FLAT_PREFIX; const char * GPGMEPLUG_ENC_FLAT_SEPARATOR; const char * GPGMEPLUG_ENC_FLAT_POSTFIX; int __GPGMEPLUG_ENCRYPTED_CODE_IS_BINARY; // end-of(these must be set by subclasses) public: #define CRYPTPLUG_CERT_DOES_NEVER_EXPIRE 365000 #define CRYPTPLUG_ERR_WRONG_KEY_USAGE 0x7070 /*! \ingroup groupGeneral \brief This function sets up all internal structures. Plugins that need no initialization should provide an empty implementation. The method returns \c true if the initialization was successful and \c false otherwise. Before this function is called, no other plugin functions should be called; the behavior is undefined in this case. \note This function must be implemented by each plug-in using this API specification. */ bool initialize( void ); /*! \ingroup groupGeneral \brief This function frees all internal structures. Plugins that do not keep any internal structures should provide an empty implementation. After this function has been called, no other plugin functions should be called; the behavior is undefined in this case. \note This function must be implemented by each plug-in using this API specification. */ //void deinitialize( void ); /*! \ingroup groupGeneral \brief This function returns \c true if the specified feature is available in the plugin, and \c false otherwise. Not all plugins will support all features; a complete Sphinx implementation will support all features contained in the enum, however. \note This function must be implemented by each plug-in using this API specification. */ bool hasFeature( Feature ); /*! \ingroup groupSignCryptAct \brief Information record returned by signing and by encrypting functions - this record should be used together with a corresponding \c free_StructuringInfo() function call. Use this information to compose a MIME object containing signed and/or encrypted content (or to build a text frame around your flat non-MIME message body, resp.) If value returned in \c makeMimeObject is TRUE the text strings returned in \c contentTypeMain and \c contentDispMain and \c contentTEncMain (and, if required, \c content[..]Version and \c bodyTextVersion and \c content[..]Sig) should be used to compose a respective MIME object.
If FALSE the texts returned in \c flatTextPrefix and \c flatTextSeparator and \c flatTextPostfix are to be used instead.
Allways either the \c content[..] and \c bodyTextVersion parameters or the \c flatText[..] parameters are holding valid data - never both of them may be used simultaneously as plugins will just ignore the parameters not matching their \c makeMimeObject setting. When creating your MIME object please observe these common rules: \li Parameters named \c contentType[..] and \c contentDisp[..] and \c contentTEnc[..] will return the values for the respective MIME headers 'Content-Type' and 'Content-Disposition' and 'Content-Transfer-Encoding'. The following applies to these parameters: \li The relevant MIME part may only be created if the respective \c contentType[..] parameter is holding a non-zero-length string. If the \c contentType[..] parameter value is invalid or holding an empty string the respective \c contentDisp[..] and \c contentTEnc[..] parameters should be ignored. \li If the respective \c contentDisp[..] or \c contentTEnc[..] parameter is NULL or holding a zero-length string it is up to you whether you want to add the relevant MIME header yourself, but since it in in the responsibility of the plugin implementors to provide you with all neccessary 'Content-[..]' header information you should not need to define them if they are not returned by the signing or encrypting function - otherwise this may be considered as a bug in the plugin and you could report the missing MIME header information to the address returned by the \c bugURL() function. If \c makeMultiMime returns FALSE the \c contentTypeMain returned must not be altered but used to specify a single part mime object holding the code bloc, e.g. this is used for 'enveloped-data' single part MIME objects. In this case you should ignore both the \c content[..]Version and \c content[..]Code parameters. If \c makeMultiMime returns TRUE also the following rules apply: \li If \c includeCleartext is TRUE you should include the cleartext as first part of our multipart MIME object, typically this is TRUE when signing mails but FALSE when encrypting. \li The \c contentTypeMain returned typically starts with "multipart/" while providing a "protocol" and a "micalg" parameter: just add an appropriate \c "; boundary=[your \c boundary \c string]" to get the complete Content-Type value to be used for the MIME object embedding both the signed part and the signature part (or - in case of encrypting - the version part and the code part, resp.). \li If \c contentTypeVersion is holding a non-zero-length string an additional MIME part must added immediately before the code part, this version part's MIME headers must have the unaltered values of \c contentTypeVersion and (if they are holding non-zero-length strings) \c contentDispVersion and \c contentTEncVersion, the unaltered contents of \c bodyTextVersion must be it's body. \li The value returned in \c contentTypeCode is specifying the complete Content-Type to be used for this multipart MIME object's signature part (or - in case of encrypting - for the code part following after the version part, resp.), you should not add/change/remove anything here but just use it's unaltered value for specifying the Content-Type header of the respective MIME part. \li The same applies to the \c contentDispCode value: just use it's unaltered value to specify the Content-Disposition header entry of the respective MIME part. \li The same applies to the \c contentTEncCode value: just use it's unaltered value to specify the Content-Transfer-Encoding header of the respective MIME part. If value returned in \c makeMimeObject is FALSE the text strings returned in \c flatTextPrefix and \c flatTextPostfix should be used to build a frame around the cleartext and the code bloc holding the signature (or - in case of encrypting - the encoded data bloc, resp.).
If \c includeCleartext is TRUE this frame should also include the cleartext as first bloc, this bloc should be divided from the code bloc by the contents of \c flatTextSeparator - typically this is used for signing but not when encrypting.
If \c includeCleartext is FALSE you should ignore both the cleartext and the \c flatTextSeparator parameter. How to use StructuringInfo data in your program: \li To compose a signed message please act as described below. \li For constructing an encrypted message just replace the \c signMessage() call by the respective \c encryptMessage() call and then proceed exactly the same way. \li In any case make sure to free your \c ciphertext and to call \c free_StructuringInfo() when you are done with processing the data returned by the signing (or encrypting, resp.) function. \verbatim char* ciphertext; StructuringInfo structInf; if( ! signMessage( cleartext, &ciphertext, certificate, &structuring ) ) { myErrorDialog( "Error: could not sign the message!" ); } else { if( structInf.makeMimeObject ) { // Build the main MIME object. // This is done by // using the header values returned in // structInf.contentTypeMain and in // structInf.contentDispMain and in // structInf.contentTEncMain. .. if( ! structInf.makeMultiMime ) { // Build the main MIME object's body. // This is done by // using the code bloc returned in // ciphertext. .. } else { // Build the encapsulated MIME parts. if( structInf.includeCleartext ) { // Build a MIME part holding the cleartext. // This is done by // using the original cleartext's headers and by // taking it's original body text. .. } if( structInf.contentTypeVersion && 0 < strlen( structInf.contentTypeVersion ) ) { // Build a MIME part holding the version information. // This is done by // using the header values returned in // structInf.contentTypeVersion and // structInf.contentDispVersion and // structInf.contentTEncVersion and by // taking the body contents returned in // structInf.bodyTextVersion. .. } if( structInf.contentTypeCode && 0 < strlen( structInf.contentTypeCode ) ) { // Build a MIME part holding the code information. // This is done by // using the header values returned in // structInf.contentTypeCode and // structInf.contentDispCode and // structInf.contentTEncCode and by // taking the body contents returned in // ciphertext. .. } else { // Plugin error! myErrorDialog( "Error: Cryptography plugin returned a main" "Content-Type=Multipart/.. but did not " "specify the code bloc's Content-Type header." "\nYou may report this bug:" "\n" + cryptplug.bugURL() ); } } } else { // Build a plain message body // based on the values returned in structInf. // Note: We do _not_ insert line breaks between the parts since // it is the plugin job to provide us with ready-to-use // texts containing all neccessary line breaks. strcpy( myMessageBody, structInf.plainTextPrefix ); if( structInf.includeCleartext ) { strcat( myMessageBody, cleartext ); strcat( myMessageBody, structInf.plainTextSeparator ); } strcat( myMessageBody, *ciphertext ); strcat( myMessageBody, structInf.plainTextPostfix ); } // free the memory that was allocated // for the ciphertext free( ciphertext ); // free the memory that was allocated // for our StructuringInfo's char* members free_StructuringInfo( &structuring ); } \endverbatim \note Make sure to call \c free_StructuringInfo() when you are done with processing the StructuringInfo data! \see free_StructuringInfo \see signMessage, encryptMessage, encryptAndSignMessage */ struct StructuringInfo { bool includeCleartext; /*!< specifies whether we should include the cleartext as first part of our multipart MIME object (or - for non-MIME messages - as flat text to be set before the ciphertext, resp.), typically this is TRUE when signing mails but FALSE when encrypting
(this parameter is relevant no matter whether \c makeMimeObject is TRUE or FALSE) */ bool makeMimeObject; /*!< specifies whether we should create a MIME object or a flat text message body */ /* the following are used for MIME messages only */ bool makeMultiMime; /*!< specifies whether we should create a 'Multipart' MIME object or a single part object, if FALSE only \c contentTypeMain, \c contentDispMain and \c contentTEncMain may be used and all other parameters have to be ignored
(ignore this parameter if \c makeMimeObject is FALSE) */ char* contentTypeMain; /*!< value of the main 'Content-Type' header
(ignore this parameter if \c makeMimeObject is FALSE) */ char* contentDispMain; /*!< value of the main 'Content-Disposition' header
(ignore this parameter if \c makeMimeObject is FALSE) */ char* contentTEncMain; /*!< value of the main 'Content-TransferEncoding' header
(ignore this parameter if \c makeMimeObject is FALSE) */ char* contentTypeVersion; /*!< 'Content-Type' of the additional version part that might preceed the code part - if NULL or zero length no version part must be created
(ignore this parameter if either \c makeMimeObject or \c makeMultiMime is FALSE) */ char* contentDispVersion; /*!< 'Content-Disposition' of the additional preceeding the code part (only valid if \c contentTypeVersion holds a non-zero-length string)
(ignore this parameter if either \c makeMimeObject or \c makeMultiMime is FALSE or if \c contentTypeVersion does not return a non-zero-length string) */ char* contentTEncVersion; /*!< 'Content-Transfer-Encoding' of the additional version part (only valid if \c contentTypeVersion holds a non-zero-length string)
(ignore this parameter if either \c makeMimeObject or \c makeMultiMime is FALSE or if \c contentTypeVersion does not return a non-zero-length string) */ char* bodyTextVersion; /*!< body text of the additional version part (only valid if \c contentTypeVersion holds a non-zero-length string)
(ignore this parameter if either \c makeMimeObject or \c makeMultiMime is FALSE or if \c contentTypeVersion does not return a non-zero-length string) */ char* contentTypeCode; /*!< 'Content-Type' of the code part holding the signature code (or the encrypted data, resp.)
(ignore this parameter if either \c makeMimeObject or \c makeMultiMime is FALSE) */ char* contentDispCode; /*!< 'Content-Disposition' of the code part
(ignore this parameter if either \c makeMimeObject or \c makeMultiMime is FALSE or if \c contentTypeCode does not return a non-zero-length string) */ char* contentTEncCode; /*!< 'Content-Type' of the code part
(ignore this parameter if either \c makeMimeObject or \c makeMultiMime is FALSE or if \c contentTypeCode does not return a non-zero-length string) */ /* the following are used for flat non-MIME messages only */ char* flatTextPrefix; /*!< text to preceed the main text (or the code bloc containing the encrypted main text, resp.)
(ignore this parameter if \c makeMimeObject is TRUE) */ char* flatTextSeparator; /*!< text to be put between the main text and the signature code bloc (not used when encrypting)
(ignore this parameter if \c makeMimeObject is TRUE or if \c includeCleartext is FALSE) */ char* flatTextPostfix; /*!< text to follow the signature code bloc (or the encrypted data bloc, resp.)
(ignore this parameter if \c makeMimeObject is TRUE) */ }; /*! \ingroup groupAdUsoInterno \brief If you are not planning to write your own cryptography plugin you should ignore this function! Usage of this function is depreciated for plugin users but highly recommended for plugin implementors since this is an internal function for initializing all char* members of a \c StructuringInfo struct.
This function must be called in any plugin's implementations of the following functions: \c signMessage()
\c encryptMessage()
\c encryptAndSignMessage() Calling this function makes sure the corresponding \c free_StructuringInfo() calls which will be embedded by your plugin's users into their code will be able to determine which of the char* members belonging to the respective's StructuringInfo had been allocated memory for during previous signing or encrypting actions. \see free_StructuringInfo, StructuringInfo \see signMessage, encryptMessage, encryptAndSignMessage */ inline void init_StructuringInfo( struct StructuringInfo* s ) { if( ! s ) return; s->includeCleartext = false; s->makeMimeObject = false; s->makeMultiMime = false; s->contentTypeMain = 0; s->contentDispMain = 0; s->contentTEncMain = 0; s->contentTypeVersion = 0; s->contentDispVersion = 0; s->contentTEncVersion = 0; s->bodyTextVersion = 0; s->contentTypeCode = 0; s->contentDispCode = 0; s->contentTEncCode = 0; s->flatTextPrefix = 0; s->flatTextSeparator = 0; s->flatTextPostfix = 0; } /*! \ingroup groupSignCryptAct \brief Important method for freeing all memory that was allocated for the char* members of a \c StructuringInfo struct - use this function after each signing or encrypting function call. \note Even when intending to call \c encryptMessage() immediately after having called \c signMessage() you first must call the \c free_StructuringInfo() function to make sure all memory is set free that was allocated for your StructuringInfo's char* members by the \c signMessage() function! \see StructuringInfo */ inline void free_StructuringInfo( struct StructuringInfo* s ) { if( ! s ) return; if( s->contentTypeMain ) free( s->contentTypeMain ); if( s->contentDispMain ) free( s->contentDispMain ); if( s->contentTEncMain ) free( s->contentTEncMain ); if( s->contentTypeVersion ) free( s->contentTypeVersion ); if( s->contentDispVersion ) free( s->contentDispVersion ); if( s->contentTEncVersion ) free( s->contentTEncVersion ); if( s->bodyTextVersion ) free( s->bodyTextVersion ); if( s->contentTypeCode ) free( s->contentTypeCode ); if( s->contentDispCode ) free( s->contentDispCode ); if( s->contentTEncCode ) free( s->contentTEncCode ); if( s->flatTextPrefix ) free( s->flatTextPrefix ); if( s->flatTextSeparator ) free( s->flatTextSeparator ); if( s->flatTextPostfix ) free( s->flatTextPostfix ); } /*! \ingroup groupSignAct */ struct SignatureMetaDataExtendedInfo { struct tm* creation_time; SigStatusFlags sigStatusFlags; char* status_text; char* keyid; char* fingerprint; char* algo; char* userid; char* name; char* comment; char** emailList; int emailCount; unsigned long algo_num; unsigned long validity; unsigned long userid_num; unsigned long keylen; unsigned long key_created; unsigned long key_expires; }; /*! \ingroup groupSignAct */ struct SignatureMetaData { char* status; struct SignatureMetaDataExtendedInfo* extended_info; int extended_info_count; int status_code; }; /*! \ingroup groupSignAct \brief Checks whether the signature of a message is valid. \c cleartext must never be 0 but be a valid pointer. If \c *cleartext > 0 then **cleartext specifies the message text that was signed and \c signaturetext is the signature itself. If \c *cleartext == 0 is an empty string then \c signaturetext is supposed to contain an opaque signed message part. After checking the data and verifying the signature the cleartext of the message will be returned in \c cleartext. The user must free the respective memory ocupied by *cleartext. Depending on the configuration, MUAs might not need to use this. If \c sigmeta is non-null, the \c SignatureMetaData object pointed to will contain meta information about the signature after the function call. */ bool checkMessageSignature( char** cleartext, const char* signaturetext, bool signatureIsBinary, int signatureLen, struct SignatureMetaData* sigmeta, char** attrOrder, const char* unknownAttrsHandling ); /*! \ingroup groupCryptAct \brief Tries to decrypt an email message \c ciphertext and returns the decrypted message in \c cleartext. The \c certificate is used for decryption. If the message could be decrypted, the function returns \c true, otherwise \c false. */ bool decryptMessage( const char* ciphertext, bool cipherIsBinary, int cipherLen, const char** cleartext, const char* certificate, int* errId, char** errTxt ); /*! \ingroup groupCryptAct \brief Combines the functionality of \c checkMessageSignature() and \c decryptMessage(). If \c certificate is \c NULL, the default certificate will be used. If \c sigmeta is non-null, the \c SignatureMetaData object pointed to will contain meta information about the signature after the function call. */ bool decryptAndCheckMessage( const char* ciphertext, bool cipherIsBinary, int cipherLen, const char** cleartext, const char* certificate, bool* signatureFound, struct SignatureMetaData* sigmeta, int* errId, char** errTxt, char** attrOrder, const char* unknownAttrsHandling ); struct DnPair { char *key; char *value; }; struct CertificateInfo { char** userid; char* userid_0_org; char* serial; char* fingerprint; char* issuer_org; char* issuer_reord; char* chainid; char* caps; unsigned long created; unsigned long expire; int secret : 1; int invalid : 1; int expired : 1; int disabled : 1; struct DnPair *dnarray; /* parsed values from userid[0] */ }; /*! Import a certificate from memory. */ GpgME::ImportResult importCertificateFromMem( const char* data, size_t length ); }; // class CryptPlug class SMIMECryptPlug : public CryptPlug { public: SMIMECryptPlug(); }; class OpenPGPCryptPlug : public CryptPlug { public: OpenPGPCryptPlug(); }; #endif /*CRYPTPLUG_H*/ diff --git a/lib/cryptplugfactory.cpp b/lib/cryptplugfactory.cpp index 546aa3ae9..7000d9a90 100644 --- a/lib/cryptplugfactory.cpp +++ b/lib/cryptplugfactory.cpp @@ -1,119 +1,119 @@ /* cryptplugfactory.cpp This file is part of libkleopatra, the KDE key management library Copyright (c) 2001,2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifdef HAVE_CONFIG_H #include #endif #include "cryptplugfactory.h" #include "cryptplugwrapperlist.h" #include #include #include #include #include #include KMail::CryptPlugFactory * KMail::CryptPlugFactory::mSelf = 0; // // // KMail::CryptPlugFactory: backwards compat stuff (ugly) // // KMail::CryptPlugFactory::CryptPlugFactory() : Kleo::CryptoBackendFactory(), mCryptPlugWrapperList( 0 ) { mSelf = this; mCryptPlugWrapperList = new CryptPlugWrapperList(); mCryptPlugWrapperList->setAutoDelete( false ); updateCryptPlugWrapperList(); } KMail::CryptPlugFactory::~CryptPlugFactory() { mSelf = 0; delete mCryptPlugWrapperList; mCryptPlugWrapperList = 0; } KMail::CryptPlugFactory * KMail::CryptPlugFactory::instance() { if ( !mSelf ) mSelf = new CryptPlugFactory(); return mSelf; } CryptPlugWrapper * KMail::CryptPlugFactory::active() const { if ( smime() && smime()->active() ) return smime(); if ( openpgp() && openpgp()->active() ) return openpgp(); return 0; } CryptPlugWrapper * KMail::CryptPlugFactory::createForProtocol( const QString & proto ) const { QString p = proto.lower(); if ( p == "application/pkcs7-signature" || p == "application/x-pkcs7-signature" ) return smime(); if ( p == "application/pgp-signature" || p == "application/x-pgp-signature" ) return openpgp(); return 0; } CryptPlugWrapper * KMail::CryptPlugFactory::smime() const { return mCryptPlugWrapperList->findForLibName( "smime" ); } CryptPlugWrapper * KMail::CryptPlugFactory::openpgp() const { return mCryptPlugWrapperList->findForLibName( "openpgp" ); } void KMail::CryptPlugFactory::scanForBackends( QStringList * reason ) { Kleo::CryptoBackendFactory::scanForBackends( reason ); updateCryptPlugWrapperList(); } void KMail::CryptPlugFactory::updateCryptPlugWrapperList() { mCryptPlugWrapperList->clear(); for ( std::vector::const_iterator it = mBackendList.begin() ; it != mBackendList.end() ; ++it ) { if ( CryptPlugWrapper * w = dynamic_cast( (*it)->openpgp() ) ) mCryptPlugWrapperList->append( w ); if ( CryptPlugWrapper * w = dynamic_cast( (*it)->smime() ) ) mCryptPlugWrapperList->append( w ); } } #include "cryptplugfactory.moc" diff --git a/lib/backends/qgpgme/qgpgmebackend.h b/lib/cryptplugfactory.h similarity index 53% copy from lib/backends/qgpgme/qgpgmebackend.h copy to lib/cryptplugfactory.h index 44301c683..a50c3909c 100644 --- a/lib/backends/qgpgme/qgpgmebackend.h +++ b/lib/cryptplugfactory.h @@ -1,82 +1,83 @@ -/* -*- mode: C++; c-file-style: "gnu" -*- - qgpgmebackend.h +/* + cryptplugfactory.h This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2004,2005 Klarälvdalens Datakonsult AB + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ +#ifndef __KLEO_CRYPTPLUGFACTORY_H__ +#define __KLEO_CRYPTPLUGFACTORY_H__ -#ifndef __KLEO_QGPGMEBACKEND_H__ -#define __KLEO_QGPGMEBACKEND_H__ +#include "kleo/cryptobackendfactory.h" -#include "kleo/cryptobackend.h" - -class CryptPlugWrapper; +#include +#ifndef LIBKLEOPATRA_NO_COMPAT namespace Kleo { - class CryptoConfig; + //typedef CryptoBackendFactory CryptPlugFactory KDE_DEPRECATED; } -class QGpgMECryptoConfig; -class QString; -namespace Kleo { +class CryptPlugWrapper; +class CryptPlugWrapperList; - class QGpgMEBackend : public Kleo::CryptoBackend { - public: - QGpgMEBackend(); - ~QGpgMEBackend(); +namespace KMail { - QString name() const; - QString displayName() const; + class KDE_EXPORT CryptPlugFactory : public Kleo::CryptoBackendFactory { + Q_OBJECT + protected: + CryptPlugFactory(); + ~CryptPlugFactory(); - CryptoConfig * config() const; + public: + static CryptPlugFactory * instance(); + + CryptPlugWrapper * active() const; + CryptPlugWrapper * smime() const; + CryptPlugWrapper * openpgp() const; - Protocol * openpgp() const; - Protocol * smime() const; - Protocol * protocol( const char * name ) const; + CryptPlugWrapperList & list() const { return *mCryptPlugWrapperList; } - bool checkForOpenPGP( QString * reason=0 ) const; - bool checkForSMIME( QString * reason=0 ) const; - bool checkForProtocol( const char * name, QString * reason ) const; + CryptPlugWrapper * createForProtocol( const QString & proto ) const; - bool supportsOpenPGP() const { return true; } - bool supportsSMIME() const { return true; } - bool supportsProtocol( const char * name ) const; + void scanForBackends( QStringList * reason ); - const char * enumerateProtocols( int i ) const; + private: + void updateCryptPlugWrapperList(); private: - mutable QGpgMECryptoConfig * mCryptoConfig; - mutable CryptPlugWrapper * mOpenPGPProtocol; - mutable CryptPlugWrapper * mSMIMEProtocol; + CryptPlugFactory( const CryptPlugFactory & ); + void operator=( const CryptPlugFactory & ); + CryptPlugWrapperList * mCryptPlugWrapperList; + + static CryptPlugFactory * mSelf; }; } +#endif - -#endif // __KLEO_QGPGMEBACKEND_H__ +#endif // __KLEO_CRYPTPLUGFACTORY_H__ diff --git a/lib/cryptplugwrapperlist.cpp b/lib/cryptplugwrapperlist.cpp new file mode 100644 index 000000000..3ff38ddd8 --- /dev/null +++ b/lib/cryptplugwrapperlist.cpp @@ -0,0 +1,34 @@ +/* -*- c++ -*- + + CRYPTPLUG - an independent cryptography plug-in + API. CryptPlugWrapperList holds any number of crypto plug-ins. + + Copyright (C) 2001 by Klarälvdalens Datakonsult AB + + CRYPTPLUG is free software; you can redistribute it and/or modify + it under the terms of GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + CRYPTPLUG is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "cryptplugwrapperlist.h" + +CryptPlugWrapper * CryptPlugWrapperList::findForLibName( const QString & libName ) const +{ + for ( QPtrListIterator it( *this ) ; it.current() ; ++it ) + if ( (*it)->libName().find( libName, 0, false ) >= 0 ) + return *it; + return 0; +} diff --git a/lib/cryptplugwrapperlist.h b/lib/cryptplugwrapperlist.h new file mode 100644 index 000000000..3fab5799c --- /dev/null +++ b/lib/cryptplugwrapperlist.h @@ -0,0 +1,37 @@ +/* -*- Mode: C++ -*- + + CRYPTPLUG - an independent cryptography plug-in + API. CryptPlugWrapperList holds any number of crypto plug-ins. + + Copyright (C) 2001,2004 by Klarälvdalens Datakonsult AB + + CRYPTPLUG is free software; you can redistribute it and/or modify + it under the terms of GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + CRYPTPLUG is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#ifndef __CRYPTPLUGWRAPPERLIST_H__ +#define __CRYPTPLUGWRAPPERLIST_H__ + +#include "cryptplugwrapper.h" + +#include + +class CryptPlugWrapperList : public QPtrList +{ +public: + CryptPlugWrapper * findForLibName( const QString & libName ) const; +}; + +typedef QPtrListIterator CryptPlugWrapperListIterator; + +#endif diff --git a/lib/kleo/cryptobackend.cpp b/lib/kleo/cryptobackend.cpp index 6da71bc9e..7a779c8ed 100644 --- a/lib/kleo/cryptobackend.cpp +++ b/lib/kleo/cryptobackend.cpp @@ -1,36 +1,36 @@ /* kleo/cryptobackend.cpp This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2005 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #include "cryptobackend.h" const char Kleo::CryptoBackend::OpenPGP[] = "OpenPGP"; const char Kleo::CryptoBackend::SMIME[] = "SMIME"; diff --git a/lib/kleo/cryptobackend.h b/lib/kleo/cryptobackend.h index 948e9b1d1..8d1f42e70 100644 --- a/lib/kleo/cryptobackend.h +++ b/lib/kleo/cryptobackend.h @@ -1,119 +1,119 @@ /* kleo/cryptobackend.h This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004,2005 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifndef __KLEO_CRYPTOBACKEND_H__ #define __KLEO_CRYPTOBACKEND_H__ namespace Kleo { class CryptoConfig; class KeyListJob; class KeyGenerationJob; class ImportJob; class ExportJob; class DownloadJob; class DeleteJob; class EncryptJob; class DecryptJob; class SignJob; class VerifyDetachedJob; class VerifyOpaqueJob; class SignEncryptJob; class DecryptVerifyJob; class RefreshKeysJob; class SpecialJob; } class QString; class QVariant; template class QMap; namespace Kleo { class CryptoBackend { public: class Protocol; static const char OpenPGP[]; static const char SMIME[]; virtual ~CryptoBackend() {} virtual QString name() const = 0; virtual QString displayName() const = 0; virtual bool checkForOpenPGP( QString * reason=0 ) const = 0; virtual bool checkForSMIME( QString * reason=0 ) const = 0; virtual bool checkForProtocol( const char * name, QString * reason=0 ) const = 0; virtual bool supportsOpenPGP() const = 0; virtual bool supportsSMIME() const = 0; virtual bool supportsProtocol( const char * name ) const = 0; virtual CryptoConfig * config() const = 0; virtual Protocol * openpgp() const = 0; virtual Protocol * smime() const = 0; virtual Protocol * protocol( const char * name ) const = 0; virtual const char * enumerateProtocols( int i ) const = 0; }; class CryptoBackend::Protocol { public: virtual ~Protocol() {} virtual QString name() const = 0; virtual QString displayName() const = 0; virtual KeyListJob * keyListJob( bool remote=false, bool includeSigs=false, bool validate=false ) const = 0; virtual EncryptJob * encryptJob( bool armor=false, bool textmode=false ) const = 0; virtual DecryptJob * decryptJob() const = 0; virtual SignJob * signJob( bool armor=false, bool textMode=false ) const = 0; virtual VerifyDetachedJob * verifyDetachedJob( bool textmode=false) const = 0; virtual VerifyOpaqueJob * verifyOpaqueJob( bool textmode=false ) const = 0; virtual KeyGenerationJob * keyGenerationJob() const = 0; virtual ImportJob * importJob() const = 0; virtual ExportJob * publicKeyExportJob( bool armor=false ) const = 0; virtual ExportJob * secretKeyExportJob( bool armor=false ) const = 0; virtual DownloadJob * downloadJob( bool armor=false ) const = 0; virtual DeleteJob * deleteJob() const = 0; virtual SignEncryptJob * signEncryptJob( bool armor=false, bool textMode=false ) const = 0; virtual DecryptVerifyJob * decryptVerifyJob( bool textmode=false ) const = 0; virtual RefreshKeysJob * refreshKeysJob() const = 0; virtual SpecialJob * specialJob( const char * type, const QMap & args ) const = 0; }; } #endif // __KLEO_CRYPTOBACKEND_H__ diff --git a/lib/kleo/cryptobackendfactory.cpp b/lib/kleo/cryptobackendfactory.cpp index f4520f776..c56a7096f 100644 --- a/lib/kleo/cryptobackendfactory.cpp +++ b/lib/kleo/cryptobackendfactory.cpp @@ -1,275 +1,275 @@ /* cryptobackendfactory.cpp This file is part of libkleopatra, the KDE key management library Copyright (c) 2001,2004,2005 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifdef HAVE_CONFIG_H #include #endif #include "cryptobackendfactory.h" #include #if 0 // disabled for kde-3.3 #include #include #include #include #endif #include #include #include #include #include #include #include #include #include #include Kleo::CryptoBackendFactory * Kleo::CryptoBackendFactory::mSelf = 0; static const char * availableProtocols[] = { "Chiasmus", "OpenPGP", "SMIME", }; static const unsigned int numAvailableProtocols = sizeof availableProtocols / sizeof *availableProtocols; Kleo::CryptoBackendFactory::CryptoBackendFactory() : QObject( qApp, "CryptoBackendFactory::instance()" ), mConfigObject( 0 ), mAvailableProtocols( availableProtocols, availableProtocols + numAvailableProtocols ) { mBackendList.push_back( new QGpgMEBackend() ); #if 0 // disabled for kde-3.3 mBackendList.push_back( new PGP2Backend() ); mBackendList.push_back( new PGP5Backend() ); mBackendList.push_back( new PGP6Backend() ); mBackendList.push_back( new GPG1Backend() ); #endif mBackendList.push_back( new ChiasmusBackend() ); scanForBackends(); readConfig(); mSelf = this; // last! } Kleo::CryptoBackendFactory::~CryptoBackendFactory() { mSelf = 0; // first! for ( std::vector::iterator it = mBackendList.begin() ; it != mBackendList.end() ; ++it ) { delete *it; *it = 0; } delete mConfigObject; mConfigObject = 0; } Kleo::CryptoBackendFactory * Kleo::CryptoBackendFactory::instance() { if ( !mSelf ) mSelf = new CryptoBackendFactory(); return mSelf; } // const Kleo::CryptoBackend* Kleo::CryptoBackendFactory::smimeBackend() const { // return mSMIMEBackend; // } // const Kleo::CryptoBackend* Kleo::CryptoBackendFactory::openpgpBackend() const { // return mOpenPGPBackend; // } const Kleo::CryptoBackend::Protocol * Kleo::CryptoBackendFactory::smime() const { const BackendMap::const_iterator it = mBackends.find( "SMIME" ); if ( it == mBackends.end() ) return 0; if ( !it->second ) return 0; return it->second->smime(); } const Kleo::CryptoBackend::Protocol * Kleo::CryptoBackendFactory::openpgp() const { const BackendMap::const_iterator it = mBackends.find( "OpenPGP" ); if ( it == mBackends.end() ) return 0; if ( !it->second ) return 0; return it->second->openpgp(); } const Kleo::CryptoBackend::Protocol * Kleo::CryptoBackendFactory::protocol( const char * name ) const { const BackendMap::const_iterator it = mBackends.find( name ); if ( it == mBackends.end() ) return 0; if ( !it->second ) return 0; return it->second->protocol( name ); } Kleo::CryptoConfig * Kleo::CryptoBackendFactory::config() const { // ## should we use mSMIMEBackend? mOpenPGPBackend? backend(0) i.e. always qgpgme? return backend( 0 ) ? backend( 0 )->config() : 0; } bool Kleo::CryptoBackendFactory::hasBackends() const { return !mBackendList.empty(); } void Kleo::CryptoBackendFactory::scanForBackends( QStringList * reasons ) { for ( std::vector::const_iterator it = mBackendList.begin() ; it != mBackendList.end() ; ++it ) { assert( *it ); for ( int i = 0 ; const char * protocol = (*it)->enumerateProtocols( i ) ; ++i ) { QString reason; if ( (*it)->supportsProtocol( protocol ) && !(*it)->checkForProtocol( protocol, &reason ) ) { if ( reasons ) { reasons->push_back( i18n("While scanning for %1 support in backend %2:") .arg( protocol, (*it)->displayName() ) ); reasons->push_back( " " + reason ); } } } } } const Kleo::CryptoBackend * Kleo::CryptoBackendFactory::backend( unsigned int idx ) const { return ( idx < mBackendList.size() ) ? mBackendList[idx] : 0 ; } const Kleo::CryptoBackend * Kleo::CryptoBackendFactory::backendByName( const QString& name ) const { for ( std::vector::const_iterator it = mBackendList.begin() ; it != mBackendList.end() ; ++it ) { if ( (*it)->name() == name ) return *it; } return 0; } Kleo::BackendConfigWidget * Kleo::CryptoBackendFactory::configWidget( QWidget * parent, const char * name ) const { return new Kleo::BackendConfigWidget( mSelf, parent, name ); } KConfig* Kleo::CryptoBackendFactory::configObject() const { if ( !mConfigObject ) // this is unsafe. We're a lib, used by concurrent apps. mConfigObject = new KConfig( "libkleopatrarc" ); return mConfigObject; } void Kleo::CryptoBackendFactory::setSMIMEBackend( const CryptoBackend* backend ) { setProtocolBackend( "SMIME", backend ); } void Kleo::CryptoBackendFactory::setOpenPGPBackend( const CryptoBackend* backend ) { setProtocolBackend( "OpenPGP", backend ); } void Kleo::CryptoBackendFactory::setProtocolBackend( const char * protocol, const CryptoBackend * backend ) { const QString name = backend ? backend->name() : QString::null ; KConfigGroup group( configObject(), "Backends" ); group.writeEntry( protocol, name ); configObject()->sync(); mBackends[protocol] = backend; } static const char * defaultBackend( const char * proto ) { static const struct { const char * proto; const char * backend; } defaults[] = { { "OpenPGP", "gpgme" }, { "SMIME", "gpgme" }, { "Chiasmus", "chiasmus" }, }; for ( unsigned int i = 0 ; i < sizeof defaults / sizeof *defaults ; ++i ) if ( qstricmp( proto, defaults[i].proto ) == 0 ) return defaults[i].backend; return 0; } void Kleo::CryptoBackendFactory::readConfig() { mBackends.clear(); const KConfigGroup group( configObject(), "Backends" ); for ( ProtocolSet::const_iterator it = mAvailableProtocols.begin(), end = mAvailableProtocols.end() ; it != end ; ++it ) { const QString backend = group.readEntry( *it, defaultBackend( *it ) ); mBackends[*it] = backendByName( backend ); } } const char * Kleo::CryptoBackendFactory::enumerateProtocols( int i ) const { if ( i < 0 || static_cast( i ) >= mAvailableProtocols.size() ) return 0; return mAvailableProtocols[i]; } namespace { class CaseInsensitiveString { const char * m; public: CaseInsensitiveString( const char * s ) : m( s ) {} #define make_operator( op ) \ bool operator op( const CaseInsensitiveString & other ) const { \ return qstricmp( m, other.m ) op 0; \ } \ bool operator op( const char * other ) const { \ return qstricmp( m, other ) op 0; \ } make_operator( == ) make_operator( != ) make_operator( < ) make_operator( > ) make_operator( <= ) make_operator( >= ) #undef make_operator operator const char *() const { return m; } }; #define make_ext_operator( op, inv_op ) \ inline bool operator op( const char * lhs, const CaseInsensitiveString & rhs ) { \ return rhs.operator inv_op( lhs ); \ } make_ext_operator( ==, == ) make_ext_operator( !=, != ) make_ext_operator( <, > ) make_ext_operator( >, < ) make_ext_operator( <=, >= ) make_ext_operator( >=, <= ) #undef make_ext_operator } bool Kleo::CryptoBackendFactory::knowsAboutProtocol( const char * name ) const { return std::find( mAvailableProtocols.begin(), mAvailableProtocols.end(), CaseInsensitiveString( name ) ) != mAvailableProtocols.end(); } #include "cryptobackendfactory.moc" diff --git a/lib/kleo/cryptobackendfactory.h b/lib/kleo/cryptobackendfactory.h index 453757ea6..7a54e9fd1 100644 --- a/lib/kleo/cryptobackendfactory.h +++ b/lib/kleo/cryptobackendfactory.h @@ -1,117 +1,117 @@ /* kleo/cryptobackendfactory.h This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004,2005 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifndef __KLEO_CRYPTOBACKENDFACTORY_H__ #define __KLEO_CRYPTOBACKENDFACTORY_H__ #include #include "cryptobackend.h" #include #include #include namespace Kleo { class BackendConfigWidget; } class QString; class KConfig; namespace Kleo { struct lt_i_str { bool operator()( const char * one, const char * two ) const { return qstricmp( one, two ) < 0; } }; class KDE_EXPORT CryptoBackendFactory : public QObject { Q_OBJECT protected: CryptoBackendFactory(); ~CryptoBackendFactory(); public: static CryptoBackendFactory * instance(); const CryptoBackend::Protocol * smime() const; const CryptoBackend::Protocol * openpgp() const; const CryptoBackend::Protocol * protocol( const char * name ) const; CryptoConfig * config() const; const CryptoBackend * backend( unsigned int idx ) const; bool hasBackends() const; Kleo::BackendConfigWidget * configWidget( QWidget * parent=0, const char * name=0 ) const; KConfig* configObject() const; // The preferred backend for smime (can be 0) - currently unused //const CryptoBackend* smimeBackend() const; // The preferred backend for openpgp (can be 0) - currently unused //const CryptoBackend* openpgpBackend() const; // For BackendConfigWidget to save the configuration // 0 means no backend selected. void setSMIMEBackend( const CryptoBackend* backend ); void setOpenPGPBackend( const CryptoBackend* backend ); void setProtocolBackend( const char * name, const CryptoBackend * backend ); void scanForBackends( QStringList * reasons=0 ); const char * enumerateProtocols( int i ) const; bool knowsAboutProtocol( const char * name ) const; protected: std::vector mBackendList; mutable KConfig* mConfigObject; typedef std::map BackendMap; BackendMap mBackends; typedef std::vector ProtocolSet; ProtocolSet mAvailableProtocols; private: const CryptoBackend * backendByName( const QString& name ) const; void readConfig(); CryptoBackendFactory( const CryptoBackendFactory & ); void operator=( const CryptoBackendFactory & ); static CryptoBackendFactory * mSelf; }; } #endif // __KLEO_CRYPTOBACKENDFACTORY_H__ diff --git a/lib/kleo/cryptoconfig.h b/lib/kleo/cryptoconfig.h index 745ad0469..6ed0cfec0 100644 --- a/lib/kleo/cryptoconfig.h +++ b/lib/kleo/cryptoconfig.h @@ -1,382 +1,382 @@ /* cryptoconfig.h This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifndef CRYPTOCONFIG_H #define CRYPTOCONFIG_H #ifdef __cplusplus /* we read this file from a C compiler, and are only interested in the * enums... */ #include /* Start reading this file from the bottom up :) */ namespace Kleo { /** * Description of a single option */ class CryptoConfigEntry { public: #endif /* __cplusplus */ /** @li basic This option should always be offered to the user. @li advanced This option may be offered to advanced users. @li expert This option should only be offered to expert users. */ enum Level { Level_Basic = 0, Level_Advanced = 1, Level_Expert = 2 }; /** Type of the argument @li ArgType_None The option is set or not set, but no argument. @li ArgType_String An unformatted string. @li ArgType_Int A signed integer number. @li ArgType_UInt An unsigned integer number. @li ArgType_Path A string that describes the pathname of a file. The file does not necessarily need to exist. Separated from string so that e.g. a KURLRequester can be used. @li ArgType_DirPath A string that describes the pathname of a directory. The directory does not necessarily need to exist. Separated from path so that e.g. a KURLRequester can be used which only allows directories to be selected. @li ArgType_URL A URL @li ArgType_LDAPURL A LDAP URL Separated from URL so that a more specific widget can be shown, hiding the url syntax */ enum ArgType { ArgType_None = 0, ArgType_String = 1, ArgType_Int = 2, ArgType_UInt = 3, ArgType_Path = 4, ArgType_URL = 5, ArgType_LDAPURL = 6, ArgType_DirPath = 7 }; #ifdef __cplusplus virtual ~CryptoConfigEntry() {} /** * Return the internal name of this entry */ virtual QString name() const = 0; /** * @return user-visible description of this entry */ virtual QString description() const = 0; /** * @return true if the argument is optional */ virtual bool isOptional() const = 0; /** * @return true if the argument can be given multiple times */ virtual bool isList() const = 0; /** * @return true if the argument can be changed at runtime */ virtual bool isRuntime() const = 0; /** * User level */ virtual Level level() const = 0; /** * Argument type */ virtual ArgType argType() const = 0; /** * Return true if the option is set, i.e. different from default */ virtual bool isSet() const = 0; /** * Return value as a bool (only allowed for ArgType_None) */ virtual bool boolValue() const = 0; /** * Return value as a string (available for all argtypes) * The returned string can be empty (explicitely set to empty) or null (not set). */ virtual QString stringValue() const = 0; /** * Return value as a signed int */ virtual int intValue() const = 0; /** * Return value as an unsigned int */ virtual unsigned int uintValue() const = 0; /** * Return value as a URL (only meaningful for Path and URL argtypes) */ virtual KURL urlValue() const = 0; /** * Return number of times the option is set (only valid for ArgType_None, if isList()) */ virtual unsigned int numberOfTimesSet() const = 0; /** * Return value as a list of strings (mostly meaningful for String, Path and URL argtypes, if isList()) */ virtual QStringList stringValueList() const = 0; /** * Return value as a list of signed ints */ virtual QValueList intValueList() const = 0; /** * Return value as a list of unsigned ints */ virtual QValueList uintValueList() const = 0; /** * Return value as a list of URLs (only meaningful for Path and URL argtypes, if isList()) */ virtual KURL::List urlValueList() const = 0; /** * Reset an option to its default value */ virtual void resetToDefault() = 0; /** * Define whether the option is set or not (only allowed for ArgType_None) * #### TODO: and for options with optional args */ virtual void setBoolValue( bool ) = 0; /** * Set string value (allowed for all argtypes) */ virtual void setStringValue( const QString& ) = 0; /** * Set a new signed int value */ virtual void setIntValue( int ) = 0; /** * Set a new unsigned int value */ virtual void setUIntValue( unsigned int ) = 0; /** * Set value as a URL (only meaningful for Path (if local) and URL argtypes) */ virtual void setURLValue( const KURL& ) = 0; /** * Set the number of times the option is set (only valid for ArgType_None, if isList()) */ virtual void setNumberOfTimesSet( unsigned int ) = 0; /** * Set a new string-list value (only allowed for String, Path and URL argtypes, if isList()) */ virtual void setStringValueList( const QStringList& ) = 0; /** * Set a new list of signed int values */ virtual void setIntValueList( const QValueList& ) = 0; /** * Set a new list of unsigned int values */ virtual void setUIntValueList( const QValueList& ) = 0; /** * Set value as a URL list (only meaningful for Path (if all URLs are local) and URL argtypes, if isList()) */ virtual void setURLValueList( const KURL::List& ) = 0; /** * @return true if the value was changed */ virtual bool isDirty() const = 0; }; /** * Group containing a set of config options */ class CryptoConfigGroup { public: virtual ~CryptoConfigGroup() {} /** * Return the internal name of this group */ virtual QString name() const = 0; /** * Return the name of the icon for this group */ virtual QString iconName() const = 0; /** * @return user-visible description of this group */ virtual QString description() const = 0; /** * User level */ virtual CryptoConfigEntry::Level level() const = 0; /** * Returns the list of entries that are known by this group. * * @return list of group entry names. **/ virtual QStringList entryList() const = 0; /** * @return the configuration object for a given entry in this group * The object is owned by CryptoConfigGroup, don't delete it. * Groups cannot be nested, so all entries returned here are pure entries, no groups. */ virtual CryptoConfigEntry* entry( const QString& name ) const = 0; }; /** * Crypto config for one component (e.g. gpg-agent, dirmngr etc.) */ class CryptoConfigComponent { public: virtual ~CryptoConfigComponent() {} /** * Return the internal name of this component */ virtual QString name() const = 0; /** * Return the name of the icon for this component */ virtual QString iconName() const = 0; /** * Return user-visible description of this component */ virtual QString description() const = 0; /** * Returns the list of groups that are known about. * * @return list of group names. One of them can be "", which is the group where all * "toplevel" options (belonging to no group) are. */ virtual QStringList groupList() const = 0; /** * @return the configuration object for a given group * The object is owned by CryptoConfigComponent, don't delete it. */ virtual CryptoConfigGroup* group( const QString& name ) const = 0; }; /** * Main interface to crypto configuration. */ class CryptoConfig { public: virtual ~CryptoConfig() {} /** * Returns the list of known components (e.g. "gpg-agent", "dirmngr" etc.). * Use @ref component() to retrieve more information about each one. * @return list of component names. **/ virtual QStringList componentList() const = 0; /** * @return the configuration object for a given component * The object is owned by CryptoConfig, don't delete it. */ virtual CryptoConfigComponent* component( const QString& name ) const = 0; /** * Convenience method to get hold of a single configuration entry when * its component, group and name are known. This can be used to read * the value and/or to set a value to it. * * @return the configuration object for a single configuration entry, 0 if not found. * The object is owned by CryptoConfig, don't delete it. */ CryptoConfigEntry* entry( const QString& componentName, const QString& groupName, const QString& entryName ) const { const Kleo::CryptoConfigComponent* comp = component( componentName ); const Kleo::CryptoConfigGroup* group = comp ? comp->group( groupName ) : 0; return group ? group->entry( entryName ) : 0; } /** * Write back changes * * @param runtime If this option is set, the changes will take effect at run-time, as * far as this is possible. Otherwise, they will take effect at the next * start of the respective backend programs. */ virtual void sync( bool runtime ) = 0; /** * Tells the CryptoConfig to discard any cached information, including * all components, groups and entries. * Call this to free some memory when you won't be using the object * for some time. * DON'T call this if you're holding pointers to components, groups or entries. */ virtual void clear() = 0; }; } #endif /* __cplusplus */ #endif /* CRYPTOCONFIG_H */ diff --git a/lib/kleo/specialjob.h b/lib/kleo/decryptjob.h similarity index 54% copy from lib/kleo/specialjob.h copy to lib/kleo/decryptjob.h index 106257428..e882152a0 100644 --- a/lib/kleo/specialjob.h +++ b/lib/kleo/decryptjob.h @@ -1,86 +1,84 @@ /* - specialjob.h + decryptjob.h This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#ifndef __KLEO_SPECIALJOB_H__ -#define __KLEO_SPECIALJOB_H__ +#ifndef __KLEO_DECRYPTJOB_H__ +#define __KLEO_DECRYPTJOB_H__ #include "job.h" +#include + namespace GpgME { class Error; + class Key; + class DecryptionResult; } + namespace Kleo { /** - @short An abstract base class for protocol-specific jobs + @short An abstract base class for asynchronous decrypters - To use a SpecialJob, first obtain an instance from the - CryptoBackend implementation, connect progress() and result() - signals to suitable slots and then start the job with a call to - start(). This call might fail, in which case the SpecialJob - instance will have schedules its own destruction with a call to - QObject::deleteLater(). + To use a DecryptJob, first obtain an instance from the + CryptoBackend implementation, connect the progress() and result() + signals to suitable slots and then start the decryption with a + call to start(). This call might fail, in which case the + DecryptJob instance will have scheduled it's own destruction with + a call to QObject::deleteLater(). - After result() is emitted, the SpecialJob will schedule its own + After result() is emitted, the DecryptJob will schedule it's own destruction by calling QObject::deleteLater(). - - Parameters are set using the Qt property system. More general, or - constructor parameters are given in the call to - Kleo::CryptoBackend::Protocol::specialJob(). - - The result is made available through the result signal, and - through the read-only result property, the latter of which needs - to be defined in each SpecialJob subclass. */ - class SpecialJob : public Job { + class DecryptJob : public Job { Q_OBJECT protected: - SpecialJob( QObject * parent, const char * name ); - + DecryptJob( QObject * parent, const char * name ); public: - ~SpecialJob(); + ~DecryptJob(); /** - Starts the special operation. + Starts the decryption operation. \a cipherText is the data to + decrypt. */ - virtual GpgME::Error start() = 0; + virtual GpgME::Error start( const QByteArray & cipherText ) = 0; - virtual GpgME::Error exec() = 0; + virtual GpgME::DecryptionResult exec( const QByteArray & cipherText, + QByteArray & plainText ) = 0; signals: - void result( const GpgME::Error & result, const QVariant & data ); + void result( const GpgME::DecryptionResult & result, const QByteArray & plainText ); }; } -#endif // __KLEO_SPECIALJOB_H__ +#endif // __KLEO_DECRYPTJOB_H__ diff --git a/lib/kleo/specialjob.h b/lib/kleo/decryptverifyjob.h similarity index 51% copy from lib/kleo/specialjob.h copy to lib/kleo/decryptverifyjob.h index 106257428..f7cdb81a1 100644 --- a/lib/kleo/specialjob.h +++ b/lib/kleo/decryptverifyjob.h @@ -1,86 +1,90 @@ /* - specialjob.h + decryptverifyjob.h This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#ifndef __KLEO_SPECIALJOB_H__ -#define __KLEO_SPECIALJOB_H__ +#ifndef __KLEO_DECRYPTVERIFYJOB_H__ +#define __KLEO_DECRYPTVERIFYJOB_H__ #include "job.h" +#include + +#include + namespace GpgME { class Error; + class Key; + class DecryptionResult; + class VerificationResult; } + namespace Kleo { /** - @short An abstract base class for protocol-specific jobs + @short An abstract base class for asynchronous combined decrypters and verifiers - To use a SpecialJob, first obtain an instance from the - CryptoBackend implementation, connect progress() and result() - signals to suitable slots and then start the job with a call to - start(). This call might fail, in which case the SpecialJob - instance will have schedules its own destruction with a call to - QObject::deleteLater(). + To use a DecryptVerifyJob, first obtain an instance from the + CryptoBackend implementation, connect the progress() and result() + signals to suitable slots and then start the operation with a + call to start(). This call might fail, in which case the + DecryptVerifyJob instance will have scheduled it's own destruction with + a call to QObject::deleteLater(). - After result() is emitted, the SpecialJob will schedule its own + After result() is emitted, the DecryptVerifyJob will schedule it's own destruction by calling QObject::deleteLater(). - - Parameters are set using the Qt property system. More general, or - constructor parameters are given in the call to - Kleo::CryptoBackend::Protocol::specialJob(). - - The result is made available through the result signal, and - through the read-only result property, the latter of which needs - to be defined in each SpecialJob subclass. */ - class SpecialJob : public Job { + class DecryptVerifyJob : public Job { Q_OBJECT protected: - SpecialJob( QObject * parent, const char * name ); - + DecryptVerifyJob( QObject * parent, const char * name ); public: - ~SpecialJob(); + ~DecryptVerifyJob(); /** - Starts the special operation. + Starts the combined decryption and verification operation. + \a cipherText is the data to decrypt and later verify. */ - virtual GpgME::Error start() = 0; + virtual GpgME::Error start( const QByteArray & cipherText ) = 0; - virtual GpgME::Error exec() = 0; + /** Synchronous equivalent of start() */ + virtual std::pair + exec( const QByteArray & cipherText, QByteArray & plainText ) = 0; signals: - void result( const GpgME::Error & result, const QVariant & data ); + void result( const GpgME::DecryptionResult & decryptionresult, + const GpgME::VerificationResult & verificationresult, + const QByteArray & plainText ); }; } -#endif // __KLEO_SPECIALJOB_H__ +#endif // __KLEO_DECRYPTVERIFYJOB_H__ diff --git a/lib/kleo/specialjob.h b/lib/kleo/deletejob.h similarity index 56% copy from lib/kleo/specialjob.h copy to lib/kleo/deletejob.h index 106257428..fd70ec513 100644 --- a/lib/kleo/specialjob.h +++ b/lib/kleo/deletejob.h @@ -1,86 +1,78 @@ /* - specialjob.h + deletejob.h This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#ifndef __KLEO_SPECIALJOB_H__ -#define __KLEO_SPECIALJOB_H__ +#ifndef __KLEO_DELETEJOB_H__ +#define __KLEO_DELETEJOB_H__ #include "job.h" namespace GpgME { class Error; + class Key; } namespace Kleo { /** - @short An abstract base class for protocol-specific jobs + @short An abstract base class for asynchronous deleters - To use a SpecialJob, first obtain an instance from the - CryptoBackend implementation, connect progress() and result() - signals to suitable slots and then start the job with a call to - start(). This call might fail, in which case the SpecialJob - instance will have schedules its own destruction with a call to + To use a DeleteJob, first obtain an instance from the + CryptoBackend implementation, connect the progress() and result() + signals to suitable slots and then start the delete with a call + to start(). This call might fail, in which case the DeleteJob + instance will have scheduled it's own destruction with a call to QObject::deleteLater(). - After result() is emitted, the SpecialJob will schedule its own + After result() is emitted, the DeleteJob will schedule it's own destruction by calling QObject::deleteLater(). - - Parameters are set using the Qt property system. More general, or - constructor parameters are given in the call to - Kleo::CryptoBackend::Protocol::specialJob(). - - The result is made available through the result signal, and - through the read-only result property, the latter of which needs - to be defined in each SpecialJob subclass. */ - class SpecialJob : public Job { + class DeleteJob : public Job { Q_OBJECT protected: - SpecialJob( QObject * parent, const char * name ); - + DeleteJob( QObject * parent, const char * name ); public: - ~SpecialJob(); + ~DeleteJob(); /** - Starts the special operation. + Starts the delete operation. \a key represents the key to + delete, \a allowSecretKeyDeletion specifies if a key may also + be deleted if the secret key part is available, too. */ - virtual GpgME::Error start() = 0; - - virtual GpgME::Error exec() = 0; + virtual GpgME::Error start( const GpgME::Key & key, bool allowSecretKeyDeletion=false ) = 0; signals: - void result( const GpgME::Error & result, const QVariant & data ); + void result( const GpgME::Error & result ); }; } -#endif // __KLEO_SPECIALJOB_H__ +#endif // __KLEO_DELETEJOB_H__ diff --git a/lib/kleo/dn.cpp b/lib/kleo/dn.cpp new file mode 100644 index 000000000..2ea0f6719 --- /dev/null +++ b/lib/kleo/dn.cpp @@ -0,0 +1,512 @@ +/* + dn.cpp + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + DN parsing: + Copyright (c) 2002 g10 Code GmbH + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#include "dn.h" + +#include "oidmap.h" +#include "ui/dnattributeorderconfigwidget.h" + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +struct Kleo::DN::Private { + Private() : mRefCount( 0 ) {} + Private( const Private & other ) + : attributes( other.attributes ), + reorderedAttributes( other.reorderedAttributes ), + mRefCount( 0 ) + { + + } + + int ref() { + return ++mRefCount; + } + + int unref() { + if ( --mRefCount <= 0 ) { + delete this; + return 0; + } else + return mRefCount; + } + + int refCount() const { return mRefCount; } + + DN::Attribute::List attributes; + DN::Attribute::List reorderedAttributes; +private: + int mRefCount; +}; + +namespace { + struct DnPair { + char * key; + char * value; + }; +} + +// copied from CryptPlug and adapted to work on DN::Attribute::List: + +#define digitp(p) (*(p) >= '0' && *(p) <= '9') +#define hexdigitp(a) (digitp (a) \ + || (*(a) >= 'A' && *(a) <= 'F') \ + || (*(a) >= 'a' && *(a) <= 'f')) +#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ + *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) +#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) + +static char * +trim_trailing_spaces( char *string ) +{ + char *p, *mark; + + for( mark = NULL, p = string; *p; p++ ) { + if( isspace( *p ) ) { + if( !mark ) + mark = p; + } + else + mark = NULL; + } + if( mark ) + *mark = '\0' ; + + return string ; +} + +/* Parse a DN and return an array-ized one. This is not a validating + parser and it does not support any old-stylish syntax; gpgme is + expected to return only rfc2253 compatible strings. */ +static const unsigned char * +parse_dn_part (DnPair *array, const unsigned char *string) +{ + const unsigned char *s, *s1; + size_t n; + char *p; + + /* parse attributeType */ + for (s = string+1; *s && *s != '='; s++) + ; + if (!*s) + return NULL; /* error */ + n = s - string; + if (!n) + return NULL; /* empty key */ + p = (char*)malloc (n+1); + + + memcpy (p, string, n); + p[n] = 0; + trim_trailing_spaces ((char*)p); + // map OIDs to their names: + for ( unsigned int i = 0 ; i < numOidMaps ; ++i ) + if ( !strcasecmp ((char*)p, oidmap[i].oid) ) { + free( p ); + p = strdup( oidmap[i].name ); + break; + } + array->key = p; + string = s + 1; + + if (*string == '#') + { /* hexstring */ + string++; + for (s=string; hexdigitp (s); s++) + s++; + n = s - string; + if (!n || (n & 1)) + return NULL; /* empty or odd number of digits */ + n /= 2; + array->value = p = (char*)malloc (n+1); + + + for (s1=string; n; s1 += 2, n--) + *p++ = xtoi_2 (s1); + *p = 0; + } + else + { /* regular v3 quoted string */ + for (n=0, s=string; *s; s++) + { + if (*s == '\\') + { /* pair */ + s++; + if (*s == ',' || *s == '=' || *s == '+' + || *s == '<' || *s == '>' || *s == '#' || *s == ';' + || *s == '\\' || *s == '\"' || *s == ' ') + n++; + else if (hexdigitp (s) && hexdigitp (s+1)) + { + s++; + n++; + } + else + return NULL; /* invalid escape sequence */ + } + else if (*s == '\"') + return NULL; /* invalid encoding */ + else if (*s == ',' || *s == '=' || *s == '+' + || *s == '<' || *s == '>' || *s == '#' || *s == ';' ) + break; + else + n++; + } + + array->value = p = (char*)malloc (n+1); + + + for (s=string; n; s++, n--) + { + if (*s == '\\') + { + s++; + if (hexdigitp (s)) + { + *p++ = xtoi_2 (s); + s++; + } + else + *p++ = *s; + } + else + *p++ = *s; + } + *p = 0; + } + return s; +} + + +/* Parse a DN and return an array-ized one. This is not a validating + parser and it does not support any old-stylish syntax; gpgme is + expected to return only rfc2253 compatible strings. */ +static Kleo::DN::Attribute::List +parse_dn( const unsigned char * string ) { + if ( !string ) + return QValueVector(); + + QValueVector result; + while (*string) + { + while (*string == ' ') + string++; + if (!*string) + break; /* ready */ + + DnPair pair = { 0, 0 }; + string = parse_dn_part (&pair, string); + if (!string) + goto failure; + if ( pair.key && pair.value ) + result.push_back( Kleo::DN::Attribute( QString::fromUtf8( pair.key ), + QString::fromUtf8( pair.value ) ) ); + free( pair.key ); + free( pair.value ); + + while (*string == ' ') + string++; + if (*string && *string != ',' && *string != ';' && *string != '+') + goto failure; /* invalid delimiter */ + if (*string) + string++; + } + return result; + +failure: + return QValueVector(); +} + +static QValueVector +parse_dn( const QString & dn ) { + return parse_dn( (const unsigned char*)dn.utf8().data() ); +} + +static QString +serialise( const QValueVector & dn ) { + QStringList result; + for ( QValueVector::const_iterator it = dn.begin() ; it != dn.end() ; ++it ) + if ( !(*it).name().isEmpty() && !(*it).value().isEmpty() ) + result.push_back( (*it).name().stripWhiteSpace() + '=' + (*it).value().stripWhiteSpace() ); + return result.join( "," ); +} + +static Kleo::DN::Attribute::List +reorder_dn( const Kleo::DN::Attribute::List & dn ) { + const QStringList & attrOrder = Kleo::DNAttributeMapper::instance()->attributeOrder(); + + Kleo::DN::Attribute::List unknownEntries; + Kleo::DN::Attribute::List result; + unknownEntries.reserve( dn.size() ); + result.reserve( dn.size() ); + + // find all unknown entries in their order of appearance + for ( Kleo::DN::const_iterator it = dn.begin(); it != dn.end(); ++it ) + if ( attrOrder.find( (*it).name() ) == attrOrder.end() ) + unknownEntries.push_back( *it ); + + // process the known attrs in the desired order + for ( QStringList::const_iterator oit = attrOrder.begin() ; oit != attrOrder.end() ; ++oit ) + if ( *oit == "_X_" ) { + // insert the unknown attrs + std::copy( unknownEntries.begin(), unknownEntries.end(), + std::back_inserter( result ) ); + unknownEntries.clear(); // don't produce dup's + } else { + for ( Kleo::DN::const_iterator dnit = dn.begin() ; dnit != dn.end() ; ++dnit ) + if ( (*dnit).name() == *oit ) + result.push_back( *dnit ); + } + + return result; +} + +// +// +// class DN +// +// + +Kleo::DN::DN() { + d = new Private(); + d->ref(); +} + +Kleo::DN::DN( const QString & dn ) { + d = new Private(); + d->ref(); + d->attributes = parse_dn( dn ); +} + +Kleo::DN::DN( const char * utf8DN ) { + d = new Private(); + d->ref(); + if ( utf8DN ) + d->attributes = parse_dn( (const unsigned char*)utf8DN ); +} + +Kleo::DN::DN( const DN & other ) + : d( other.d ) +{ + if ( d ) d->ref(); +} + +Kleo::DN::~DN() { + if ( d ) d->unref(); +} + +const Kleo::DN & Kleo::DN::operator=( const DN & that ) { + if ( this->d == that.d ) + return *this; + + if ( that.d ) + that.d->ref(); + if ( this->d ) + this->d->unref(); + + this->d = that.d; + + return *this; +} + +QString Kleo::DN::prettyDN() const { + if ( !d ) + return QString::null; + if ( d->reorderedAttributes.empty() ) + d->reorderedAttributes = reorder_dn( d->attributes ); + return serialise( d->reorderedAttributes ); +} + +QString Kleo::DN::dn() const { + return d ? serialise( d->attributes ) : QString::null ; +} + +void Kleo::DN::detach() { + if ( !d ) { + d = new Kleo::DN::Private(); + d->ref(); + } else if ( d->refCount() > 1 ) { + Kleo::DN::Private * d_save = d; + d = new Kleo::DN::Private( *d ); + d->ref(); + d_save->unref(); + } +} + +void Kleo::DN::append( const Attribute & attr ) { + detach(); + d->attributes.push_back( attr ); + d->reorderedAttributes.clear(); +} + +QString Kleo::DN::operator[]( const QString & attr ) const { + if ( !d ) + return QString::null; + const QString attrUpper = attr.upper(); + for ( QValueVector::const_iterator it = d->attributes.begin() ; + it != d->attributes.end() ; ++it ) + if ( (*it).name() == attrUpper ) + return (*it).value(); + return QString::null; +} + +static QValueVector empty; + +Kleo::DN::const_iterator Kleo::DN::begin() const { + return d ? d->attributes.begin() : empty.begin() ; +} + +Kleo::DN::const_iterator Kleo::DN::end() const { + return d ? d->attributes.end() : empty.end() ; +} + + +///////////////////// + +namespace { + struct ltstr { + bool operator()( const char * s1, const char * s2 ) const { + return qstrcmp( s1, s2 ) < 0 ; + } + }; +} + +static const char * defaultOrder[] = { + "CN", "L", "_X_", "OU", "O", "C" +}; + +std::pair attributeLabels[] = { +#define MAKE_PAIR(x,y) std::pair( x, y ) + MAKE_PAIR( "CN", I18N_NOOP("Common name") ), + MAKE_PAIR( "SN", I18N_NOOP("Surname") ), + MAKE_PAIR( "GN", I18N_NOOP("Given name") ), + MAKE_PAIR( "L", I18N_NOOP("Location") ), + MAKE_PAIR( "T", I18N_NOOP("Title") ), + MAKE_PAIR( "OU", I18N_NOOP("Organizational unit") ), + MAKE_PAIR( "O", I18N_NOOP("Organization") ), + MAKE_PAIR( "PC", I18N_NOOP("Postal code") ), + MAKE_PAIR( "C", I18N_NOOP("Country code") ), + MAKE_PAIR( "SP", I18N_NOOP("State or province") ), + MAKE_PAIR( "DC", I18N_NOOP("Domain component") ), + MAKE_PAIR( "BC", I18N_NOOP("Business category") ), + MAKE_PAIR( "EMAIL", I18N_NOOP("Email address") ), + MAKE_PAIR( "MAIL", I18N_NOOP("Mail address") ), + MAKE_PAIR( "MOBILE", I18N_NOOP("Mobile phone number") ), + MAKE_PAIR( "TEL", I18N_NOOP("Telephone number") ), + MAKE_PAIR( "FAX", I18N_NOOP("Fax number") ), + MAKE_PAIR( "STREET", I18N_NOOP("Street address") ), + MAKE_PAIR( "UID", I18N_NOOP("Unique ID") ) +#undef MAKE_PAIR +}; +static const unsigned int numAttributeLabels = sizeof attributeLabels / sizeof *attributeLabels ; + +class Kleo::DNAttributeMapper::Private { +public: + Private(); + std::map map; + QStringList attributeOrder; +}; + +Kleo::DNAttributeMapper::Private::Private() + : map( attributeLabels, attributeLabels + numAttributeLabels ) {} + +Kleo::DNAttributeMapper::DNAttributeMapper() { + d = new Private(); + const KConfigGroup config( kapp->config(), "DN" ); + d->attributeOrder = config.readListEntry( "AttributeOrder" ); + if ( d->attributeOrder.empty() ) + std::copy( defaultOrder, defaultOrder + sizeof defaultOrder / sizeof *defaultOrder, + std::back_inserter( d->attributeOrder ) ); + mSelf = this; +} + +Kleo::DNAttributeMapper::~DNAttributeMapper() { + mSelf = 0; + delete d; d = 0; +} + +Kleo::DNAttributeMapper * Kleo::DNAttributeMapper::mSelf = 0; + +const Kleo::DNAttributeMapper * Kleo::DNAttributeMapper::instance() { + if ( !mSelf ) + (void)new DNAttributeMapper(); + return mSelf; +} + +QString Kleo::DNAttributeMapper::name2label( const QString & s ) const { + const std::map::const_iterator it + = d->map.find( s.stripWhiteSpace().upper().latin1() ); + if ( it == d->map.end() ) + return QString::null; + return i18n( it->second ); +} + +QStringList Kleo::DNAttributeMapper::names() const { + QStringList result; + for ( std::map::const_iterator it = d->map.begin() ; it != d->map.end() ; ++it ) + result.push_back( it->first ); + return result; +} + +const QStringList & Kleo::DNAttributeMapper::attributeOrder() const { + return d->attributeOrder; +} + +void Kleo::DNAttributeMapper::setAttributeOrder( const QStringList & order ) { + d->attributeOrder = order; + if ( order.empty() ) + std::copy( defaultOrder, defaultOrder + sizeof defaultOrder / sizeof *defaultOrder, + std::back_inserter( d->attributeOrder ) ); + KConfigGroup config( kapp->config(), "DN" ); + config.writeEntry( "AttributeOrder", order ); +} + +Kleo::DNAttributeOrderConfigWidget * Kleo::DNAttributeMapper::configWidget( QWidget * parent, const char * name ) const { + return new DNAttributeOrderConfigWidget( mSelf, parent, name ); +} diff --git a/lib/kleo/dn.h b/lib/kleo/dn.h new file mode 100644 index 000000000..f4bd78e8e --- /dev/null +++ b/lib/kleo/dn.h @@ -0,0 +1,139 @@ +/* + dn.h + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifndef __KLEO_DN_H__ +#define __KLEO_DN_H__ + +#include +#include +#include + +class QStringList; +class QWidget; + +namespace Kleo { + class DNAttributeOrderConfigWidget; +} + +namespace Kleo { + + /** + @short DN Attribute mapper + */ + class KDE_EXPORT DNAttributeMapper { + DNAttributeMapper(); + ~DNAttributeMapper(); + public: + static const DNAttributeMapper * instance(); + + QString name2label( const QString & s ) const; + QStringList names() const; + + const QStringList & attributeOrder() const; + + void setAttributeOrder( const QStringList & order ); + + DNAttributeOrderConfigWidget * configWidget( QWidget * parent=0, const char * name=0 ) const; + + private: + class Private; + Private * d; + static DNAttributeMapper * mSelf; + }; + + /** + @short DN parser and reorderer + */ + class KDE_EXPORT DN { + public: + class Attribute; + typedef QValueVector AttributeList; + typedef AttributeList::const_iterator const_iterator; + + DN(); + DN( const QString & dn ); + DN( const char * utf8DN ); + DN( const DN & other ); + ~DN(); + + const DN & operator=( const DN & other ); + + /** @return the DN in a reordered form, according to the settings in + the [DN] group of the application's config file */ + QString prettyDN() const; + /** @return the DN in the original form */ + QString dn() const; + + QString operator[]( const QString & attr ) const; + + void append( const Attribute & attr ); + + const_iterator begin() const; + const_iterator end() const; + + private: + void detach(); + private: + class Private; + Private * d; + }; + + class KDE_EXPORT DN::Attribute { + public: + typedef DN::AttributeList List; + + Attribute( const QString & name=QString::null, const QString & value=QString::null ) + : mName( name.upper() ), mValue( value ) {} + Attribute( const Attribute & other ) + : mName( other.name() ), mValue( other.value() ) {} + + const Attribute & operator=( const Attribute & other ) { + if ( this != &other ) { + mName = other.name(); + mValue = other.value(); + } + return *this; + } + + const QString & name() const { return mName; } + const QString & value() const { return mValue; } + + void setValue( const QString & value ) { mValue = value; } + + private: + QString mName; + QString mValue; + }; + +} + +#endif // __KLEO_DN_H__ diff --git a/lib/kleo/specialjob.h b/lib/kleo/downloadjob.h similarity index 55% copy from lib/kleo/specialjob.h copy to lib/kleo/downloadjob.h index 106257428..006ab8ebd 100644 --- a/lib/kleo/specialjob.h +++ b/lib/kleo/downloadjob.h @@ -1,86 +1,83 @@ /* - specialjob.h + downloadjob.h This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#ifndef __KLEO_SPECIALJOB_H__ -#define __KLEO_SPECIALJOB_H__ +#ifndef __KLEO_DOWNLOADJOB_H__ +#define __KLEO_DOWNLOADJOB_H__ #include "job.h" +#include + namespace GpgME { class Error; } +class QStringList; + namespace Kleo { /** - @short An abstract base class for protocol-specific jobs + @short An abstract base class for asynchronous downloaders - To use a SpecialJob, first obtain an instance from the - CryptoBackend implementation, connect progress() and result() - signals to suitable slots and then start the job with a call to - start(). This call might fail, in which case the SpecialJob - instance will have schedules its own destruction with a call to + To use a DownloadJob, first obtain an instance from the + CryptoBackend implementation, connect the progress() and result() + signals to suitable slots and then start the download with a call + to start(). This call might fail, in which case the DownloadJob + instance will have scheduled it's own destruction with a call to QObject::deleteLater(). - After result() is emitted, the SpecialJob will schedule its own + After result() is emitted, the DownloadJob will schedule it's own destruction by calling QObject::deleteLater(). - - Parameters are set using the Qt property system. More general, or - constructor parameters are given in the call to - Kleo::CryptoBackend::Protocol::specialJob(). - - The result is made available through the result signal, and - through the read-only result property, the latter of which needs - to be defined in each SpecialJob subclass. */ - class SpecialJob : public Job { + class DownloadJob : public Job { Q_OBJECT protected: - SpecialJob( QObject * parent, const char * name ); - + DownloadJob( QObject * parent, const char * name ); public: - ~SpecialJob(); + ~DownloadJob(); /** - Starts the special operation. + Starts the download operation. \a fingerprints is a list of + fingerprints used to specify the list of keys downloaded. Empty + patterns are ignored. If \a fingerprints is empty, contains + only empty strings or anything other than fingerprints, the + result is undefined. */ - virtual GpgME::Error start() = 0; - - virtual GpgME::Error exec() = 0; + virtual GpgME::Error start( const QStringList & fingerprints ) = 0; signals: - void result( const GpgME::Error & result, const QVariant & data ); + void result( const GpgME::Error & result, const QByteArray & keyData ); }; } -#endif // __KLEO_SPECIALJOB_H__ +#endif // __KLEO_DOWNLOADJOB_H__ diff --git a/lib/kleo/specialjob.h b/lib/kleo/encryptjob.h similarity index 51% copy from lib/kleo/specialjob.h copy to lib/kleo/encryptjob.h index 106257428..02144656f 100644 --- a/lib/kleo/specialjob.h +++ b/lib/kleo/encryptjob.h @@ -1,86 +1,92 @@ /* - specialjob.h + encryptjob.h This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#ifndef __KLEO_SPECIALJOB_H__ -#define __KLEO_SPECIALJOB_H__ +#ifndef __KLEO_ENCRYPTJOB_H__ +#define __KLEO_ENCRYPTJOB_H__ #include "job.h" +#include + +#include + namespace GpgME { class Error; + class Key; + class EncryptionResult; } + namespace Kleo { /** - @short An abstract base class for protocol-specific jobs + @short An abstract base class for asynchronous encrypters - To use a SpecialJob, first obtain an instance from the - CryptoBackend implementation, connect progress() and result() - signals to suitable slots and then start the job with a call to - start(). This call might fail, in which case the SpecialJob - instance will have schedules its own destruction with a call to - QObject::deleteLater(). + To use a EncryptJob, first obtain an instance from the + CryptoBackend implementation, connect the progress() and result() + signals to suitable slots and then start the encryption with a + call to start(). This call might fail, in which case the + EncryptJob instance will have scheduled it's own destruction with + a call to QObject::deleteLater(). - After result() is emitted, the SpecialJob will schedule its own + After result() is emitted, the EncryptJob will schedule it's own destruction by calling QObject::deleteLater(). - - Parameters are set using the Qt property system. More general, or - constructor parameters are given in the call to - Kleo::CryptoBackend::Protocol::specialJob(). - - The result is made available through the result signal, and - through the read-only result property, the latter of which needs - to be defined in each SpecialJob subclass. */ - class SpecialJob : public Job { + class EncryptJob : public Job { Q_OBJECT protected: - SpecialJob( QObject * parent, const char * name ); - + EncryptJob( QObject * parent, const char * name ); public: - ~SpecialJob(); + ~EncryptJob(); /** - Starts the special operation. + Starts the encryption operation. \a recipients is the a list of + keys to encrypt \a plainText to. Empty (null) keys are ignored. + + If \a alwaysTrust is true, validity checking for the keys will + not be performed, but full validity assumed for all keys + without further checks. */ - virtual GpgME::Error start() = 0; + virtual GpgME::Error start( const std::vector & recipients, + const QByteArray & plainText, bool alwaysTrust=false ) = 0; - virtual GpgME::Error exec() = 0; + virtual GpgME::EncryptionResult exec( const std::vector & recipients, + const QByteArray & plainText, + bool alwaysTrust, QByteArray & cipherText ) = 0; signals: - void result( const GpgME::Error & result, const QVariant & data ); + void result( const GpgME::EncryptionResult & result, const QByteArray & cipherText ); }; } -#endif // __KLEO_SPECIALJOB_H__ +#endif // __KLEO_ENCRYPTJOB_H__ diff --git a/lib/kleo/enum.cpp b/lib/kleo/enum.cpp new file mode 100644 index 000000000..efa4cfaa3 --- /dev/null +++ b/lib/kleo/enum.cpp @@ -0,0 +1,206 @@ +/* + kleo/enum.cpp + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#include "enum.h" + +#include + +#include +#include + +static const struct { + Kleo::CryptoMessageFormat format; + const char * displayName; + const char * configName; +} cryptoMessageFormats[] = { + { Kleo::InlineOpenPGPFormat, + I18N_NOOP("Inline OpenPGP (deprecated)"), + "inline openpgp" }, + { Kleo::OpenPGPMIMEFormat, + I18N_NOOP("OpenPGP/MIME"), + "openpgp/mime" }, + { Kleo::SMIMEFormat, + I18N_NOOP("S/MIME"), + "s/mime" }, + { Kleo::SMIMEOpaqueFormat, + I18N_NOOP("S/MIME Opaque"), + "s/mime opaque" }, +}; +static const unsigned int numCryptoMessageFormats + = sizeof cryptoMessageFormats / sizeof *cryptoMessageFormats ; + +const char * Kleo::cryptoMessageFormatToString( Kleo::CryptoMessageFormat f ) { + if ( f == AutoFormat ) + return "auto"; + for ( unsigned int i = 0 ; i < numCryptoMessageFormats ; ++i ) + if ( f == cryptoMessageFormats[i].format ) + return cryptoMessageFormats[i].configName; + return 0; +} + +QStringList Kleo::cryptoMessageFormatsToStringList( unsigned int f ) { + QStringList result; + for ( unsigned int i = 0 ; i < numCryptoMessageFormats ; ++i ) + if ( f & cryptoMessageFormats[i].format ) + result.push_back( cryptoMessageFormats[i].configName ); + return result; +} + +QString Kleo::cryptoMessageFormatToLabel( Kleo::CryptoMessageFormat f ) { + if ( f == AutoFormat ) + return i18n("Any"); + for ( unsigned int i = 0 ; i < numCryptoMessageFormats ; ++i ) + if ( f == cryptoMessageFormats[i].format ) + return i18n( cryptoMessageFormats[i].displayName ); + return QString::null; +} + +Kleo::CryptoMessageFormat Kleo::stringToCryptoMessageFormat( const QString & s ) { + const QString t = s.lower(); + for ( unsigned int i = 0 ; i < numCryptoMessageFormats ; ++i ) + if ( t == cryptoMessageFormats[i].configName ) + return cryptoMessageFormats[i].format; + return AutoFormat; +} + +unsigned int Kleo::stringListToCryptoMessageFormats( const QStringList & sl ) { + unsigned int result = 0; + for ( QStringList::const_iterator it = sl.begin() ; it != sl.end() ; ++it ) + result |= stringToCryptoMessageFormat( *it ); + return result; +} + +// For the config values used below, see also kaddressbook/editors/cryptowidget.cpp + +const char* Kleo::encryptionPreferenceToString( EncryptionPreference pref ) +{ + switch( pref ) { + case UnknownPreference: + return 0; + case NeverEncrypt: + return "never"; + case AlwaysEncrypt: + return "always"; + case AlwaysEncryptIfPossible: + return "alwaysIfPossible"; + case AlwaysAskForEncryption: + return "askAlways"; + case AskWheneverPossible: + return "askWhenPossible"; + } + return 0; // keep the compiler happy +} + +Kleo::EncryptionPreference Kleo::stringToEncryptionPreference( const QString& str ) +{ + if ( str == "never" ) + return NeverEncrypt; + if ( str == "always" ) + return AlwaysEncrypt; + if ( str == "alwaysIfPossible" ) + return AlwaysEncryptIfPossible; + if ( str == "askAlways" ) + return AlwaysAskForEncryption; + if ( str == "askWhenPossible" ) + return AskWheneverPossible; + return UnknownPreference; +} + +QString Kleo::encryptionPreferenceToLabel( EncryptionPreference pref ) +{ + switch( pref ) { + case NeverEncrypt: + return i18n( "Never Encrypt" ); + case AlwaysEncrypt: + return i18n( "Always Encrypt" ); + case AlwaysEncryptIfPossible: + return i18n( "Always Encrypt If Possible" ); + case AlwaysAskForEncryption: + return i18n( "Ask" ); + case AskWheneverPossible: + return i18n( "Ask Whenever Possible" ); + default: + return i18n( "no specific preference", "" ); + } +} + +const char* Kleo::signingPreferenceToString( SigningPreference pref ) +{ + switch( pref ) { + case UnknownSigningPreference: + return 0; + case NeverSign: + return "never"; + case AlwaysSign: + return "always"; + case AlwaysSignIfPossible: + return "alwaysIfPossible"; + case AlwaysAskForSigning: + return "askAlways"; + case AskSigningWheneverPossible: + return "askWhenPossible"; + } + return 0; // keep the compiler happy +} + +Kleo::SigningPreference Kleo::stringToSigningPreference( const QString& str ) +{ + if ( str == "never" ) + return NeverSign; + if ( str == "always" ) + return AlwaysSign; + if ( str == "alwaysIfPossible" ) + return AlwaysSignIfPossible; + if ( str == "askAlways" ) + return AlwaysAskForSigning; + if ( str == "askWhenPossible" ) + return AskSigningWheneverPossible; + return UnknownSigningPreference; +} + +QString Kleo::signingPreferenceToLabel( SigningPreference pref ) +{ + switch( pref ) { + case NeverSign: + return i18n( "Never Sign" ); + case AlwaysSign: + return i18n( "Always Sign" ); + case AlwaysSignIfPossible: + return i18n( "Always Sign If Possible" ); + case AlwaysAskForSigning: + return i18n( "Ask" ); + case AskSigningWheneverPossible: + return i18n( "Ask Whenever Possible" ); + default: + return i18n( "no specific preference", "" ); + } +} diff --git a/lib/kleo/enum.h b/lib/kleo/enum.h new file mode 100644 index 000000000..29f8e2a66 --- /dev/null +++ b/lib/kleo/enum.h @@ -0,0 +1,93 @@ +/* + kleo/enum.h + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifndef __KLEO_ENUM_H__ +#define __KLEO_ENUM_H__ + +#include + +class QString; +class QStringList; + +namespace Kleo { + + enum CryptoMessageFormat { + InlineOpenPGPFormat = 1, + OpenPGPMIMEFormat = 2, + SMIMEFormat = 4, + SMIMEOpaqueFormat = 8, + AnyOpenPGP = InlineOpenPGPFormat|OpenPGPMIMEFormat, + AnySMIME = SMIMEOpaqueFormat|SMIMEFormat, + AutoFormat = AnyOpenPGP|AnySMIME + }; + + KDE_EXPORT QString cryptoMessageFormatToLabel( CryptoMessageFormat f ); + + KDE_EXPORT const char * cryptoMessageFormatToString( CryptoMessageFormat f ); + KDE_EXPORT QStringList cryptoMessageFormatsToStringList( unsigned int f ); + KDE_EXPORT CryptoMessageFormat stringToCryptoMessageFormat( const QString & s ); + KDE_EXPORT unsigned int stringListToCryptoMessageFormats( const QStringList & sl ); + + enum Action { + Conflict, DoIt, DontDoIt, Ask, AskOpportunistic, Impossible + }; + + enum EncryptionPreference { + UnknownPreference = 0, + NeverEncrypt = 1, + AlwaysEncrypt = 2, + AlwaysEncryptIfPossible = 3, + AlwaysAskForEncryption = 4, + AskWheneverPossible = 5, + MaxEncryptionPreference = AskWheneverPossible + }; + + KDE_EXPORT QString encryptionPreferenceToLabel( EncryptionPreference pref ); + KDE_EXPORT const char* encryptionPreferenceToString( EncryptionPreference pref ); + KDE_EXPORT EncryptionPreference stringToEncryptionPreference( const QString& str ); + + enum SigningPreference { + UnknownSigningPreference = 0, + NeverSign = 1, + AlwaysSign = 2, + AlwaysSignIfPossible = 3, + AlwaysAskForSigning = 4, + AskSigningWheneverPossible = 5, + MaxSigningPreference = AskSigningWheneverPossible + }; + + KDE_EXPORT QString signingPreferenceToLabel( SigningPreference pref ) KDE_EXPORT; + KDE_EXPORT const char* signingPreferenceToString( SigningPreference pref ) KDE_EXPORT; + KDE_EXPORT SigningPreference stringToSigningPreference( const QString& str ); +} + +#endif // __KLEO_CRYPTOBACKEND_H__ diff --git a/lib/kleo/specialjob.h b/lib/kleo/exportjob.h similarity index 56% copy from lib/kleo/specialjob.h copy to lib/kleo/exportjob.h index 106257428..d6a0db185 100644 --- a/lib/kleo/specialjob.h +++ b/lib/kleo/exportjob.h @@ -1,86 +1,82 @@ /* - specialjob.h + exportjob.h This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#ifndef __KLEO_SPECIALJOB_H__ -#define __KLEO_SPECIALJOB_H__ +#ifndef __KLEO_EXPORTJOB_H__ +#define __KLEO_EXPORTJOB_H__ #include "job.h" +#include + namespace GpgME { class Error; } +class QStringList; + namespace Kleo { /** - @short An abstract base class for protocol-specific jobs + @short An abstract base class for asynchronous exporters - To use a SpecialJob, first obtain an instance from the - CryptoBackend implementation, connect progress() and result() - signals to suitable slots and then start the job with a call to - start(). This call might fail, in which case the SpecialJob - instance will have schedules its own destruction with a call to + To use a ExportJob, first obtain an instance from the + CryptoBackend implementation, connect the progress() and result() + signals to suitable slots and then start the export with a call + to start(). This call might fail, in which case the ExportJob + instance will have scheduled it's own destruction with a call to QObject::deleteLater(). - After result() is emitted, the SpecialJob will schedule its own + After result() is emitted, the ExportJob will schedule it's own destruction by calling QObject::deleteLater(). - - Parameters are set using the Qt property system. More general, or - constructor parameters are given in the call to - Kleo::CryptoBackend::Protocol::specialJob(). - - The result is made available through the result signal, and - through the read-only result property, the latter of which needs - to be defined in each SpecialJob subclass. */ - class SpecialJob : public Job { + class ExportJob : public Job { Q_OBJECT protected: - SpecialJob( QObject * parent, const char * name ); - + ExportJob( QObject * parent, const char * name ); public: - ~SpecialJob(); + ~ExportJob(); /** - Starts the special operation. + Starts the export operation. \a patterns is a list of patterns + used to restrict the list of keys exported. Empty patterns are + ignored. If \a patterns is empty or contains only empty + strings, all available keys are exported. */ - virtual GpgME::Error start() = 0; - - virtual GpgME::Error exec() = 0; + virtual GpgME::Error start( const QStringList & patterns ) = 0; signals: - void result( const GpgME::Error & result, const QVariant & data ); + void result( const GpgME::Error & result, const QByteArray & keyData ); }; } -#endif // __KLEO_SPECIALJOB_H__ +#endif // __KLEO_EXPORTJOB_H__ diff --git a/lib/kleo/hierarchicalkeylistjob.cpp b/lib/kleo/hierarchicalkeylistjob.cpp new file mode 100644 index 000000000..a7a66b2fe --- /dev/null +++ b/lib/kleo/hierarchicalkeylistjob.cpp @@ -0,0 +1,158 @@ +/* + hierarchicalkeylistjob.cpp + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "hierarchicalkeylistjob.h" +#include "cryptobackend.h" +#include "keylistjob.h" + +#include + +#include +#include + +#include +#include +#include + +#include + +#include +#include + +#include + +Kleo::HierarchicalKeyListJob::HierarchicalKeyListJob( const CryptoBackend::Protocol * protocol, + bool remote, bool includeSigs, bool validating ) + : KeyListJob( 0, "Kleo::HierarchicalKeyListJob" ), + mProtocol( protocol ), + mRemote( remote ), + mIncludeSigs( includeSigs ), + mValidating( validating ), + mTruncated( false ), + mIntermediateResult(), + mJob( 0 ) +{ + assert( protocol ); +} + +Kleo::HierarchicalKeyListJob::~HierarchicalKeyListJob() { + +} + +GpgME::Error Kleo::HierarchicalKeyListJob::start( const QStringList & patterns, bool secretOnly ) { + if ( secretOnly || patterns.empty() ) + return gpg_err_make( GPG_ERR_SOURCE_GPGME, GPG_ERR_UNSUPPORTED_OPERATION ); + qCopy( patterns.begin(), patterns.end(), + std::inserter( mNextSet, mNextSet.begin() ) ); + const GpgME::Error err = startAJob(); + if ( err ) + deleteLater(); + return err; +} + +GpgME::KeyListResult Kleo::HierarchicalKeyListJob::exec( const QStringList &, bool, + std::vector & keys ) { + keys.clear(); + return GpgME::KeyListResult( gpg_err_make( GPG_ERR_SOURCE_GPGME, GPG_ERR_UNSUPPORTED_OPERATION ) ); +} + +void Kleo::HierarchicalKeyListJob::slotNextKey( const GpgME::Key & key ) { + if ( const char * chain_id = key.chainID() ) + mNextSet.insert( chain_id ); + if ( const char * fpr = key.primaryFingerprint() ) + if ( mSentSet.find( fpr ) == mSentSet.end() ) { + mSentSet.insert( fpr ); + emit nextKey( key ); + } +} + +void Kleo::HierarchicalKeyListJob::slotCancel() { + if ( mJob ) mJob->slotCancel(); + mNextSet.clear(); +} + +void Kleo::HierarchicalKeyListJob::slotResult( const GpgME::KeyListResult & res ) { + mJob = 0; + mIntermediateResult.mergeWith( res ); + std::set tmp; + std::set_difference( mNextSet.begin(), mNextSet.end(), + mScheduledSet.begin(), mScheduledSet.end(), + std::inserter( tmp, tmp.begin() ) ); + mNextSet.clear(); + std::set_difference( tmp.begin(), tmp.end(), + mSentSet.begin(), mSentSet.end(), + std::inserter( mNextSet, mNextSet.begin() ) ); + if ( mIntermediateResult.error() || mNextSet.empty() ) { + emit done(); + emit result( mIntermediateResult ); + deleteLater(); + return; + } + if ( const GpgME::Error error = startAJob() ) { // error starting the job for next keys + mIntermediateResult.mergeWith( GpgME::KeyListResult( error ) ); + emit done(); + emit result( mIntermediateResult ); + deleteLater(); + return; + } +#if 0 // FIXME + const int current = mIt - mKeys.begin(); + const int total = mKeys.size(); + emit progress( i18n("progress info: \"%1 of %2\"","%1/%2").arg( current ).arg( total ), current, total ); +#endif +} + +GpgME::Error Kleo::HierarchicalKeyListJob::startAJob() { + if ( mNextSet.empty() ) + return 0; + mJob = mProtocol->keyListJob( mRemote, mIncludeSigs, mValidating ); + assert( mJob ); // FIXME: we need a way to generate errors ourselves, + // but I don't like the dependency on gpg-error :/ + + connect( mJob, SIGNAL(nextKey(const GpgME::Key&)), SLOT(slotNextKey(const GpgME::Key&)) ); + connect( mJob, SIGNAL(result(const GpgME::KeyListResult&)), SLOT(slotResult(const GpgME::KeyListResult&)) ); + + QStringList patterns; + for ( std::set::const_iterator it = mNextSet.begin() ; it != mNextSet.end() ; ++it ) + patterns.push_back( *it ); + + mScheduledSet.insert( mNextSet.begin(), mNextSet.end() ); + mNextSet.clear(); + + return mJob->start( patterns, false ); +} + +#include "hierarchicalkeylistjob.moc" diff --git a/lib/kleo/hierarchicalkeylistjob.h b/lib/kleo/hierarchicalkeylistjob.h new file mode 100644 index 000000000..a91ff6dc0 --- /dev/null +++ b/lib/kleo/hierarchicalkeylistjob.h @@ -0,0 +1,116 @@ +/* + hierarchicalkeylistjob.h + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifndef __KLEO_HIERARCHICALKEYLISTJOB_H__ +#define __KLEO_HIERARCHICALKEYLISTJOB_H__ + +#include +#include +#include + +#include + +#include +#include + +#include + +namespace GpgME { + class Error; + class Key; +} + +namespace Kleo { + class KeyListJob; +} + +namespace Kleo { + + /** + @short A convenience job that additionally fetches all available issuers. + + To use a HierarchicalKeyListJob, pass it a CryptoBackend + implementation, connect the progress() and result() signals to + suitable slots and then start the keylisting with a call to + start(). This call might fail, in which case the + HierarchicalKeyListJob instance will have scheduled it's own + destruction with a call to QObject::deleteLater(). + + After result() is emitted, the HierarchicalKeyListJob will + schedule its own destruction by calling QObject::deleteLater(). + */ + class KDE_EXPORT HierarchicalKeyListJob : public KeyListJob { + Q_OBJECT + public: + HierarchicalKeyListJob( const CryptoBackend::Protocol * protocol, + bool remote=false, bool includeSigs=false, bool validating=false ); + ~HierarchicalKeyListJob(); + + /** + Starts the keylist operation. \a patterns is a list of patterns + used to restrict the list of keys returned. Empty patterns are + ignored. \a patterns must not be empty or contain only empty + patterns; use the normal KeyListJob for a full listing. + + The \a secretOnly parameter is ignored by + HierarchicalKeyListJob and must be set to false. + */ + GpgME::Error start( const QStringList & patterns, bool secretOnly=false ); + + GpgME::KeyListResult exec( const QStringList & patterns, bool secretOnly, + std::vector & keys ); + + private slots: + void slotResult( const GpgME::KeyListResult & ); + void slotNextKey( const GpgME::Key & key ); + /*! \reimp from Job */ + void slotCancel(); + + private: + GpgME::Error startAJob(); + + private: + const CryptoBackend::Protocol * const mProtocol; + const bool mRemote; + const bool mIncludeSigs; + const bool mValidating; + bool mTruncated; + std::set mSentSet; // keys already sent (prevent duplicates even if the backend should return them) + std::set mScheduledSet; // keys already scheduled (by starting a job for them) + std::set mNextSet; // keys to schedule for the next iteraton + GpgME::KeyListResult mIntermediateResult; + QGuardedPtr mJob; + }; + +} + +#endif // __KLEO_HIERARCHICALKEYLISTJOB_H__ diff --git a/lib/kleo/specialjob.h b/lib/kleo/importjob.h similarity index 56% copy from lib/kleo/specialjob.h copy to lib/kleo/importjob.h index 106257428..10aa90383 100644 --- a/lib/kleo/specialjob.h +++ b/lib/kleo/importjob.h @@ -1,86 +1,83 @@ /* - specialjob.h + importjob.h This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#ifndef __KLEO_SPECIALJOB_H__ -#define __KLEO_SPECIALJOB_H__ +#ifndef __KLEO_IMPORTJOB_H__ +#define __KLEO_IMPORTJOB_H__ #include "job.h" +#include + namespace GpgME { class Error; + class Key; + class ImportResult; } + namespace Kleo { /** - @short An abstract base class for protocol-specific jobs + @short An abstract base class for asynchronous importers - To use a SpecialJob, first obtain an instance from the - CryptoBackend implementation, connect progress() and result() - signals to suitable slots and then start the job with a call to - start(). This call might fail, in which case the SpecialJob - instance will have schedules its own destruction with a call to + To use a ImportJob, first obtain an instance from the + CryptoBackend implementation, connect the progress() and result() + signals to suitable slots and then start the import with a call + to start(). This call might fail, in which case the ImportJob + instance will have scheduled it's own destruction with a call to QObject::deleteLater(). - After result() is emitted, the SpecialJob will schedule its own + After result() is emitted, the ImportJob will schedule it's own destruction by calling QObject::deleteLater(). - - Parameters are set using the Qt property system. More general, or - constructor parameters are given in the call to - Kleo::CryptoBackend::Protocol::specialJob(). - - The result is made available through the result signal, and - through the read-only result property, the latter of which needs - to be defined in each SpecialJob subclass. */ - class SpecialJob : public Job { + class ImportJob : public Job { Q_OBJECT protected: - SpecialJob( QObject * parent, const char * name ); - + ImportJob( QObject * parent, const char * name ); public: - ~SpecialJob(); + ~ImportJob(); /** - Starts the special operation. + Starts the importing operation. \a keyData contains the data to + import from. */ - virtual GpgME::Error start() = 0; + virtual GpgME::Error start( const QByteArray & keyData ) = 0; - virtual GpgME::Error exec() = 0; + virtual GpgME::ImportResult exec( const QByteArray & keyData ) = 0; signals: - void result( const GpgME::Error & result, const QVariant & data ); + void result( const GpgME::ImportResult & result ); }; } -#endif // __KLEO_SPECIALJOB_H__ +#endif // __KLEO_IMPORTJOB_H__ diff --git a/lib/kleo/job.cpp b/lib/kleo/job.cpp index 723cfde32..abccca7b3 100644 --- a/lib/kleo/job.cpp +++ b/lib/kleo/job.cpp @@ -1,113 +1,113 @@ /* job.cpp This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004,2005 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifdef HAVE_CONFIG_H #include #endif #include "job.h" #include "keylistjob.h" #include "encryptjob.h" #include "decryptjob.h" #include "decryptverifyjob.h" #include "signjob.h" #include "signencryptjob.h" #include "verifydetachedjob.h" #include "verifyopaquejob.h" #include "keygenerationjob.h" #include "importjob.h" #include "exportjob.h" #include "downloadjob.h" #include "deletejob.h" #include "refreshkeysjob.h" #include "specialjob.h" #include #include Kleo::Job::Job( QObject * parent, const char * name ) : QObject( parent, name ) { if ( qApp ) connect( qApp, SIGNAL(aboutToQuit()), SLOT(slotCancel()) ); } Kleo::Job::~Job() { } void Kleo::Job::showErrorDialog( QWidget *, const QString & ) const { kdDebug() << "Kleo::Job::showErrorDialog() should be reimplemented in Kleo::Job subclasses!" << endl; } #define make_job_subclass(x) \ Kleo::x::x( QObject * parent, const char * name ) : Job( parent, name ) {} \ Kleo::x::~x() {} make_job_subclass(KeyListJob) make_job_subclass(EncryptJob) make_job_subclass(DecryptJob) make_job_subclass(DecryptVerifyJob) make_job_subclass(SignJob) make_job_subclass(SignEncryptJob) make_job_subclass(VerifyDetachedJob) make_job_subclass(VerifyOpaqueJob) make_job_subclass(KeyGenerationJob) make_job_subclass(ImportJob) make_job_subclass(ExportJob) make_job_subclass(DownloadJob) make_job_subclass(DeleteJob) make_job_subclass(RefreshKeysJob) make_job_subclass(SpecialJob) #undef make_job_subclass #include "job.moc" #include "keylistjob.moc" #include "encryptjob.moc" #include "decryptjob.moc" #include "decryptverifyjob.moc" #include "signjob.moc" #include "signencryptjob.moc" #include "verifydetachedjob.moc" #include "verifyopaquejob.moc" #include "keygenerationjob.moc" #include "importjob.moc" #include "exportjob.moc" #include "downloadjob.moc" #include "deletejob.moc" #include "refreshkeysjob.moc" #include "specialjob.moc" diff --git a/lib/kleo/specialjob.h b/lib/kleo/job.h similarity index 50% copy from lib/kleo/specialjob.h copy to lib/kleo/job.h index 106257428..6b762a04b 100644 --- a/lib/kleo/specialjob.h +++ b/lib/kleo/job.h @@ -1,86 +1,79 @@ /* - specialjob.h + job.h This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#ifndef __KLEO_SPECIALJOB_H__ -#define __KLEO_SPECIALJOB_H__ +#ifndef __KLEO_JOB_H__ +#define __KLEO_JOB_H__ -#include "job.h" +#include +#include -namespace GpgME { - class Error; -} +class QWidget; namespace Kleo { /** - @short An abstract base class for protocol-specific jobs - - To use a SpecialJob, first obtain an instance from the - CryptoBackend implementation, connect progress() and result() - signals to suitable slots and then start the job with a call to - start(). This call might fail, in which case the SpecialJob - instance will have schedules its own destruction with a call to - QObject::deleteLater(). + @short An abstract base class for asynchronous crypto operations - After result() is emitted, the SpecialJob will schedule its own - destruction by calling QObject::deleteLater(). + During the operation, you might receive progress updates through + the progress() signal as they arrive, but an implementation is + free to not send progress information. You should show a busy + progressbar until the first progress() signal is received. - Parameters are set using the Qt property system. More general, or - constructor parameters are given in the call to - Kleo::CryptoBackend::Protocol::specialJob(). + The done() signal is emitted _before_ the result() signals of + subclasses and should be used to hide and/or reset progress bars, + not to learn of the end of the operation. Use the result() + signals for that. - The result is made available through the result signal, and - through the read-only result property, the latter of which needs - to be defined in each SpecialJob subclass. + To cancel the operation, simply call slotCancel(). The result() + signal of subclasses will still be emitted, though, and will + carry the information that the operation was canceled. */ - class SpecialJob : public Job { + class Job : public QObject { Q_OBJECT protected: - SpecialJob( QObject * parent, const char * name ); - + Job( QObject * parent, const char * name ); public: - ~SpecialJob(); + ~Job(); - /** - Starts the special operation. - */ - virtual GpgME::Error start() = 0; + virtual void showErrorDialog( QWidget * parent=0, const QString & caption=QString::null ) const; - virtual GpgME::Error exec() = 0; + public slots: + virtual void slotCancel() = 0; signals: - void result( const GpgME::Error & result, const QVariant & data ); + void progress( const QString & what, int current, int total ); + void done(); }; } -#endif // __KLEO_SPECIALJOB_H__ +#endif // __KLEO_JOB_H__ diff --git a/lib/kleo/kconfigbasedkeyfilter.cpp b/lib/kleo/kconfigbasedkeyfilter.cpp new file mode 100644 index 000000000..89d18e799 --- /dev/null +++ b/lib/kleo/kconfigbasedkeyfilter.cpp @@ -0,0 +1,251 @@ +/* + kconfigbasedkeyfilter.cpp + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "kconfigbasedkeyfilter.h" + +#include +#include + +static const struct { + const char * name; + GpgME::Key::OwnerTrust trust; + GpgME::UserID::Validity validity; +} ownerTrustAndValidityMap[] = { + { "unknown", GpgME::Key::Unknown, GpgME::UserID::Unknown }, + { "undefined", GpgME::Key::Undefined, GpgME::UserID::Undefined }, + { "never", GpgME::Key::Never, GpgME::UserID::Never }, + { "marginal", GpgME::Key::Marginal, GpgME::UserID::Marginal }, + { "full", GpgME::Key::Full, GpgME::UserID::Full }, + { "ultimate", GpgME::Key::Ultimate, GpgME::UserID::Ultimate }, +}; + +static GpgME::Key::OwnerTrust map2OwnerTrust( const QString & s ) { + for ( unsigned int i = 0 ; i < sizeof ownerTrustAndValidityMap / sizeof *ownerTrustAndValidityMap ; ++i ) + if ( s.lower() == ownerTrustAndValidityMap[i].name ) + return ownerTrustAndValidityMap[i].trust; + return ownerTrustAndValidityMap[0].trust; +} + +static GpgME::UserID::Validity map2Validity( const QString & s ) { + for ( unsigned int i = 0 ; i < sizeof ownerTrustAndValidityMap / sizeof *ownerTrustAndValidityMap ; ++i ) + if ( s.lower() == ownerTrustAndValidityMap[i].name ) + return ownerTrustAndValidityMap[i].validity; + return ownerTrustAndValidityMap[0].validity; +} + + +Kleo::KConfigBasedKeyFilter::KConfigBasedKeyFilter( const KConfigBase & config ) + : KeyFilter(), + mSpecificity( 0 ), + mItalic( false ), + mBold( false ), + mStrikeOut( false ), + mUseFullFont( false ), + mRevoked( DoesNotMatter ), + mExpired( DoesNotMatter ), + mDisabled( DoesNotMatter ), + mRoot( DoesNotMatter ), + mCanEncrypt( DoesNotMatter ), + mCanSign( DoesNotMatter ), + mCanCertify( DoesNotMatter ), + mCanAuthenticate( DoesNotMatter ), + mHasSecret( DoesNotMatter ), + mIsOpenPGP( DoesNotMatter ), + mWasValidated( DoesNotMatter ), + mOwnerTrust( LevelDoesNotMatter ), + mOwnerTrustReferenceLevel( GpgME::Key::Unknown ), + mValidity( LevelDoesNotMatter ), + mValidityReferenceLevel( GpgME::UserID::Unknown ) +{ + mFgColor = config.readColorEntry( "foreground-color" ); + mBgColor = config.readColorEntry( "background-color" ); + mName = config.readEntry( "name", i18n("") ); + mIcon = config.readEntry( "icon" ); + if ( config.hasKey( "font" ) ) { + mUseFullFont = true; + mFont = config.readFontEntry( "font" ); + } else { + mItalic = config.readBoolEntry( "font-italic", false ); + mBold = config.readBoolEntry( "font-bold", false ); + } + mStrikeOut = config.readBoolEntry( "font-strikeout", false ); +#ifdef SET +#undef SET +#endif +#define SET(member,key) \ + if ( config.hasKey( key ) ) { \ + member = config.readBoolEntry( key ) ? Set : NotSet ; \ + ++mSpecificity; \ + } + SET( mRevoked, "is-revoked" ); + SET( mExpired, "is-expired" ); + SET( mDisabled, "is-disabled" ); + SET( mRoot, "is-root-certificate" ); + SET( mCanEncrypt, "can-encrypt" ); + SET( mCanSign, "can-sign" ); + SET( mCanCertify, "can-certify" ); + SET( mCanAuthenticate, "can-authenticate" ); + SET( mHasSecret, "has-secret-key" ); + SET( mIsOpenPGP, "is-openpgp-key" ); + SET( mWasValidated, "was-validated" ); +#undef SET + static const struct { + const char * prefix; + LevelState state; + } prefixMap[] = { + { "is-", Is }, + { "is-not-", IsNot }, + { "is-at-least-", IsAtLeast }, + { "is-at-most-", IsAtMost }, + }; + for ( unsigned int i = 0 ; i < sizeof prefixMap / sizeof *prefixMap ; ++i ) { + const QString key = QString( prefixMap[i].prefix ) + "ownertrust"; + if ( config.hasKey( key ) ) { + mOwnerTrust = prefixMap[i].state; + mOwnerTrustReferenceLevel = map2OwnerTrust( config.readEntry( key ) ); + ++mSpecificity; + break; + } + } + for ( unsigned int i = 0 ; i < sizeof prefixMap / sizeof *prefixMap ; ++i ) { + const QString key = QString( prefixMap[i].prefix ) + "validity"; + if ( config.hasKey( key ) ) { + mValidity = prefixMap[i].state; + mValidityReferenceLevel = map2Validity( config.readEntry( key ) ); + ++mSpecificity; + break; + } + } +} + +Kleo::KConfigBasedKeyFilter::~KConfigBasedKeyFilter() { + +} + +bool Kleo::KConfigBasedKeyFilter::matches( const GpgME::Key & key ) const { +#ifdef MATCH +#undef MATCH +#endif +#define MATCH(member,method) \ + if ( member != DoesNotMatter && key.method() != bool( member == Set ) ) \ + return false +#define IS_MATCH(what) MATCH( m##what, is##what ) +#define CAN_MATCH(what) MATCH( mCan##what, can##what ) + IS_MATCH( Revoked ); + IS_MATCH( Expired ); + IS_MATCH( Disabled ); + IS_MATCH( Root ); + CAN_MATCH( Encrypt ); + CAN_MATCH( Sign ); + CAN_MATCH( Certify ); + CAN_MATCH( Authenticate ); + MATCH( mHasSecret, isSecret ); +#undef MATCH + if ( mIsOpenPGP != DoesNotMatter && + bool( key.protocol() == GpgME::Context::OpenPGP ) != bool( mIsOpenPGP == Set ) ) + return false; + if ( mWasValidated != DoesNotMatter && + bool( key.keyListMode() & GpgME::Context::Validate ) != bool( mWasValidated == Set ) ) + return false; + switch ( mOwnerTrust ) { + default: + case LevelDoesNotMatter: + break; + case Is: + if ( key.ownerTrust() != mOwnerTrustReferenceLevel ) + return false; + break; + case IsNot: + if ( key.ownerTrust() == mOwnerTrustReferenceLevel ) + return false; + break; + case IsAtLeast: + if ( (int)key.ownerTrust() < (int)mOwnerTrustReferenceLevel ) + return false; + break; + case IsAtMost: + if ( (int)key.ownerTrust() > (int)mOwnerTrustReferenceLevel ) + return false; + break; + } + const GpgME::UserID uid = key.userID(0); + switch ( mValidity ) { + default: + case LevelDoesNotMatter: + break; + case Is: + if ( uid.validity() != mValidityReferenceLevel ) + return false; + break; + case IsNot: + if ( uid.validity() == mValidityReferenceLevel ) + return false; + break; + case IsAtLeast: + if ( (int)uid.validity() < (int)mValidityReferenceLevel ) + return false; + break; + case IsAtMost: + if ( (int)uid.validity() > (int)mValidityReferenceLevel ) + return false; + break; + } + return true; +} + +static inline QFont resizedFont( QFont font, int pointSize, bool strike ) { + font.setPointSize( pointSize ); + if ( strike ) + font.setStrikeOut( true ); + return font; +} + +static inline QFont adapt( QFont font, bool it, bool b, bool strike ) { + if ( it ) + font.setItalic( true ); + if ( b ) + font.setBold( true ); + if ( strike ) + font.setStrikeOut( true ); + return font; +} + +QFont Kleo::KConfigBasedKeyFilter::font( const QFont & f ) const { + if ( mUseFullFont ) + return resizedFont( mFont, f.pointSize(), mStrikeOut ); + else + return adapt( f, mItalic, mBold, mStrikeOut ); +} diff --git a/lib/kleo/kconfigbasedkeyfilter.h b/lib/kleo/kconfigbasedkeyfilter.h new file mode 100644 index 000000000..42c083080 --- /dev/null +++ b/lib/kleo/kconfigbasedkeyfilter.h @@ -0,0 +1,104 @@ +/* + kconfigbasedkeyfilter.h + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifndef __KLEO_KCONFIGBASEDKEYFILTER_H__ +#define __KLEO_KCONFIGBASEDKEYFILTER_H__ + +#include "keyfilter.h" + +#include +#include +#include + +#include + +class KConfigBase; + +namespace Kleo { + + class KConfigBasedKeyFilter : public KeyFilter { + public: + explicit KConfigBasedKeyFilter( const KConfigBase & config ); + ~KConfigBasedKeyFilter(); + bool matches( const GpgME::Key & key ) const; + + unsigned int specificity() const { return mSpecificity; } + + QColor fgColor() const { return mFgColor; } + QColor bgColor() const { return mBgColor; } + QFont font( const QFont & ) const; + QString name() const { return mName; } + QString icon() const { return mIcon; } + + private: + QColor mFgColor, mBgColor; + QString mName; + QString mIcon; + unsigned int mSpecificity; + bool mItalic; + bool mBold; + bool mStrikeOut; + bool mUseFullFont; + QFont mFont; + + enum TriState { + DoesNotMatter = 0, + Set = 1, + NotSet = 2 + }; + TriState mRevoked; + TriState mExpired; + TriState mDisabled; + TriState mRoot; + TriState mCanEncrypt; + TriState mCanSign; + TriState mCanCertify; + TriState mCanAuthenticate; + TriState mHasSecret; + TriState mIsOpenPGP; + TriState mWasValidated; + enum LevelState { + LevelDoesNotMatter = 0, + Is = 1, + IsNot = 2, + IsAtLeast = 3, + IsAtMost = 4 + }; + LevelState mOwnerTrust; + GpgME::Key::OwnerTrust mOwnerTrustReferenceLevel; + LevelState mValidity; + GpgME::UserID::Validity mValidityReferenceLevel; + }; + +} + +#endif // __KLEO_KCONFIGBASEDKEYFILTER_H__ diff --git a/lib/backends/chiasmus/chiasmuslibrary.h b/lib/kleo/keyfilter.h similarity index 61% copy from lib/backends/chiasmus/chiasmuslibrary.h copy to lib/kleo/keyfilter.h index 1759b4fc7..f10fba9bf 100644 --- a/lib/backends/chiasmus/chiasmuslibrary.h +++ b/lib/kleo/keyfilter.h @@ -1,68 +1,68 @@ -/* -*- mode: C++; c-file-style: "gnu" -*- - chiasmuslibrary.h +/* + keyfilter.h This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ +#ifndef __KLEO_KEYFILTER_H__ +#define __KLEO_KEYFILTER_H__ -#ifndef __KLEO_CHIASMUSLIBRARY_H__ -#define __KLEO_CHIASMUSLIBRARY_H__ - -#include -#include +namespace GpgME { + class Key; +} -class KLibrary; +class QFont; +class QColor; +class QString; namespace Kleo { /** - @short small helper class to load xia.o through xia.so and make - the functionality available. + @short An abstract base class key filters + */ - class ChiasmusLibrary { - ChiasmusLibrary(); - ~ChiasmusLibrary(); + class KeyFilter { public: - static const ChiasmusLibrary * instance(); - static void deleteInstance(); - - int perform( const QValueVector & args ) const; - private: - typedef int ( *main_func )( int, char** ); - main_func chiasmus( QString * reason=0 ) const; - - private: - static ChiasmusLibrary * self; - mutable KLibrary * mXiaLibrary; + virtual ~KeyFilter() {} + virtual bool matches( const GpgME::Key & key ) const = 0; + + virtual unsigned int specificity() const = 0; + + // not sure if we want these here, but for the time being, it's + // the easiest way: + virtual QColor fgColor() const = 0; + virtual QColor bgColor() const = 0; + virtual QFont font( const QFont & ) const = 0; + virtual QString name() const = 0; + virtual QString icon() const = 0; }; } - -#endif // __KLEO_CHIASMUSLIBRARY_H__ +#endif // __KLEO_KEYFILTER_H__ diff --git a/lib/kleo/keyfiltermanager.cpp b/lib/kleo/keyfiltermanager.cpp new file mode 100644 index 000000000..14932801c --- /dev/null +++ b/lib/kleo/keyfiltermanager.cpp @@ -0,0 +1,118 @@ +/* + keyfiltermanager.cpp + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "keyfiltermanager.h" +#include "kconfigbasedkeyfilter.h" + +#include "cryptobackendfactory.h" + +#include + +#include +#include +#include +#include + +#include + +namespace { + template + struct Delete { + void operator()( T * item ) { delete item; } + }; +} + +struct Kleo::KeyFilterManager::Private { + void clear() { + std::for_each( filters.begin(), filters.end(), Delete() ); + filters.clear(); + } + + QValueVector filters; +}; + +Kleo::KeyFilterManager * Kleo::KeyFilterManager::mSelf = 0; + +Kleo::KeyFilterManager::KeyFilterManager( QObject * parent, const char * name ) + : QObject( parent, name ), d( 0 ) +{ + mSelf = this; + d = new Private(); + // ### DF: doesn't a KStaticDeleter work more reliably? + if ( qApp ) + connect( qApp, SIGNAL(aboutToQuit()), SLOT(deleteLater()) ); + reload(); +} + +Kleo::KeyFilterManager::~KeyFilterManager() { + mSelf = 0; + if ( d ) + d->clear(); + delete d; d = 0; +} + +Kleo::KeyFilterManager * Kleo::KeyFilterManager::instance() { + if ( !mSelf ) + mSelf = new Kleo::KeyFilterManager(); + return mSelf; +} + +const Kleo::KeyFilter * Kleo::KeyFilterManager::filterMatching( const GpgME::Key & key ) const { + for ( QValueVector::const_iterator it = d->filters.begin() ; it != d->filters.end() ; ++it ) + if ( (*it)->matches( key ) ) + return *it; + return 0; +} + +static inline bool by_increasing_specificity( const Kleo::KeyFilter * left, const Kleo::KeyFilter * right ) { + return left->specificity() > right->specificity(); +} + +void Kleo::KeyFilterManager::reload() { + d->clear(); + + KConfig * config = Kleo::CryptoBackendFactory::instance()->configObject(); + if ( !config ) + return; + const QStringList groups = config->groupList().grep( QRegExp( "^Key Filter #\\d+$" ) ); + for ( QStringList::const_iterator it = groups.begin() ; it != groups.end() ; ++it ) { + const KConfigGroup cfg( config, *it ); + d->filters.push_back( new KConfigBasedKeyFilter( cfg ) ); + } + std::stable_sort( d->filters.begin(), d->filters.end(), by_increasing_specificity ); +} + +#include "keyfiltermanager.moc" diff --git a/lib/kleo/cryptobackend.cpp b/lib/kleo/keyfiltermanager.h similarity index 62% copy from lib/kleo/cryptobackend.cpp copy to lib/kleo/keyfiltermanager.h index 6da71bc9e..25353d71a 100644 --- a/lib/kleo/cryptobackend.cpp +++ b/lib/kleo/keyfiltermanager.h @@ -1,36 +1,69 @@ /* - kleo/cryptobackend.cpp + keyfiltermanager.h This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#include "cryptobackend.h" +#ifndef __KLEO_KEYFILTERMANAGER_H__ +#define __KLEO_KEYFILTERMANAGER_H__ -const char Kleo::CryptoBackend::OpenPGP[] = "OpenPGP"; -const char Kleo::CryptoBackend::SMIME[] = "SMIME"; +#include +#include +namespace GpgME { + class Key; +} + +namespace Kleo { + class KeyFilter; +} + +namespace Kleo { + + class KDE_EXPORT KeyFilterManager : public QObject { + Q_OBJECT + protected: + KeyFilterManager( QObject * parent=0, const char * name=0 ); + ~KeyFilterManager(); + + public: + static KeyFilterManager * instance(); + + const KeyFilter * filterMatching( const GpgME::Key & key ) const; + + void reload(); + + private: + class Private; + Private * d; + static KeyFilterManager * mSelf; + }; + +} + +#endif // __KLEO_KEYFILTERMANAGER_H__ diff --git a/lib/kleo/specialjob.h b/lib/kleo/keygenerationjob.h similarity index 54% copy from lib/kleo/specialjob.h copy to lib/kleo/keygenerationjob.h index 106257428..f78152c5c 100644 --- a/lib/kleo/specialjob.h +++ b/lib/kleo/keygenerationjob.h @@ -1,86 +1,81 @@ /* - specialjob.h + keygenerationjob.h This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#ifndef __KLEO_SPECIALJOB_H__ -#define __KLEO_SPECIALJOB_H__ +#ifndef __KLEO_KEYGENERATIONJOB_H__ +#define __KLEO_KEYGENERATIONJOB_H__ #include "job.h" +#include + namespace GpgME { class Error; + class KeyGenerationResult; } + namespace Kleo { /** - @short An abstract base class for protocol-specific jobs + @short An abstract base class for asynchronous key generation - To use a SpecialJob, first obtain an instance from the - CryptoBackend implementation, connect progress() and result() - signals to suitable slots and then start the job with a call to - start(). This call might fail, in which case the SpecialJob - instance will have schedules its own destruction with a call to - QObject::deleteLater(). + To use a KeyGenerationJob, first obtain an instance from the + CryptoBackend implementation, connect the progress() and result() + signals to suitable slots and then start the key generation with + a call to start(). This call might fail, in which case the + KeyGenerationJob instance will have scheduled it's own + destruction with a call to QObject::deleteLater(). - After result() is emitted, the SpecialJob will schedule its own + After result() is emitted, the KeyGenerationJob will schedule it's own destruction by calling QObject::deleteLater(). - - Parameters are set using the Qt property system. More general, or - constructor parameters are given in the call to - Kleo::CryptoBackend::Protocol::specialJob(). - - The result is made available through the result signal, and - through the read-only result property, the latter of which needs - to be defined in each SpecialJob subclass. */ - class SpecialJob : public Job { + class KeyGenerationJob : public Job { Q_OBJECT protected: - SpecialJob( QObject * parent, const char * name ); - + KeyGenerationJob( QObject * parent, const char * name ); public: - ~SpecialJob(); + ~KeyGenerationJob(); /** - Starts the special operation. + Starts the key generation operation. \a parameters is a + backend-specific string containing the paramaters of the key to + create (length, capabilities, etc). */ - virtual GpgME::Error start() = 0; - - virtual GpgME::Error exec() = 0; + virtual GpgME::Error start( const QString & parameters ) = 0; signals: - void result( const GpgME::Error & result, const QVariant & data ); + void result( const GpgME::KeyGenerationResult & result, const QByteArray & pubKeyData ); }; } -#endif // __KLEO_SPECIALJOB_H__ +#endif // __KLEO_KEYGENERATIONJOB_H__ diff --git a/lib/kleo/keylistjob.h b/lib/kleo/keylistjob.h new file mode 100644 index 000000000..c419ad47d --- /dev/null +++ b/lib/kleo/keylistjob.h @@ -0,0 +1,96 @@ +/* + keylistjob.h + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifndef __KLEO_KEYLISTJOB_H__ +#define __KLEO_KEYLISTJOB_H__ + +#include "job.h" + +#include + +namespace GpgME { + class Error; + class Key; + class KeyListResult; +} + +class QStringList; + +namespace Kleo { + + /** + @short An abstract base class for asynchronous key listers + + To use a KeyListJob, first obtain an instance from the + CryptoBackend implementation, connect the nextKey(), progress() + and result() signals to suitable slots and then start the key + listing with a call to start(). This call might fail, in which + case the KeylistJob instance will have schedules it's own + destruction with a call to QObject::deleteLater(). + + During keylisting, you will receive new key objects through the + nextKey() signal as they arrive. After result() is emitted, the + KeyListJob will schedule it's own destruction by calling + QObject::deleteLater(). + */ + class KeyListJob : public Job { + Q_OBJECT + protected: + KeyListJob( QObject * parent, const char * name ); + + public: + ~KeyListJob(); + + /** + Starts the keylist operation. \a pattern is a list of patterns + used to restrict the list of keys returned. Empty patterns are + ignored. If \a pattern is empty or contains only empty strings, + all keys are returned (however, the backend is free to truncate + the result and should do so; when this happens, it will be + reported by the reult object). + + If \a secretOnly is true, only keys for which the secret key is + also available are returned. Use this if you need to select a + key for signing. + */ + virtual GpgME::Error start( const QStringList & patterns, bool secretOnly=false ) = 0; + + virtual GpgME::KeyListResult exec( const QStringList & patterns, bool secretOnly, std::vector & keys ) = 0; + + signals: + void nextKey( const GpgME::Key & key ); + void result( const GpgME::KeyListResult & result ); + }; + +} + +#endif // __KLEO_KEYLISTJOB_H__ diff --git a/lib/kleo/multideletejob.cpp b/lib/kleo/multideletejob.cpp new file mode 100644 index 000000000..32596e78f --- /dev/null +++ b/lib/kleo/multideletejob.cpp @@ -0,0 +1,110 @@ +/* + multideletejob.cpp + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "multideletejob.h" +#include "cryptobackend.h" +#include "deletejob.h" + +#include + +#include +#include +#include + +#include + +#include + +Kleo::MultiDeleteJob::MultiDeleteJob( const CryptoBackend::Protocol * protocol ) + : Job( 0, "Kleo::MultiDeleteJob" ), + mProtocol( protocol ), + mJob( 0 ) +{ + assert( protocol ); +} + +Kleo::MultiDeleteJob::~MultiDeleteJob() { + +} + +GpgME::Error Kleo::MultiDeleteJob::start( const std::vector & keys, bool allowSecretKeyDeletion ) { + mKeys = keys; + mAllowSecretKeyDeletion = allowSecretKeyDeletion; + mIt = mKeys.begin(); + + const GpgME::Error err = startAJob(); + + if ( err ) + deleteLater(); + return err; +} + +void Kleo::MultiDeleteJob::slotCancel() { + if ( mJob ) mJob->slotCancel(); + mIt = mKeys.end(); +} + +void Kleo::MultiDeleteJob::slotResult( const GpgME::Error & err ) { + mJob = 0; + GpgME::Error error = err; + if ( error || // error in last op + mIt == mKeys.end() || // (shouldn't happen) + ++mIt == mKeys.end() || // was the last key + (error = startAJob()) ) { // error starting the job for the new key + emit done(); + emit result( error, error && mIt != mKeys.end() ? *mIt : GpgME::Key::null ); + deleteLater(); + return; + } + + const int current = mIt - mKeys.begin(); + const int total = mKeys.size(); + emit progress( i18n("progress info: \"%1 of %2\"","%1/%2").arg( current ).arg( total ), current, total ); +} + +GpgME::Error Kleo::MultiDeleteJob::startAJob() { + if ( mIt == mKeys.end() ) + return 0; + mJob = mProtocol->deleteJob(); + assert( mJob ); // FIXME: we need a way to generate errors ourselves, + // but I don't like the dependency on gpg-error :/ + + connect( mJob, SIGNAL(result(const GpgME::Error&)), SLOT(slotResult(const GpgME::Error&)) ); + + return mJob->start( *mIt, mAllowSecretKeyDeletion ); +} + +#include "multideletejob.moc" diff --git a/lib/kleo/multideletejob.h b/lib/kleo/multideletejob.h new file mode 100644 index 000000000..5b995adaf --- /dev/null +++ b/lib/kleo/multideletejob.h @@ -0,0 +1,101 @@ +/* + multideletejob.h + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifndef __KLEO_MULTIDELETEJOB_H__ +#define __KLEO_MULTIDELETEJOB_H__ + +#include +#include + +#include +#include + +#include + +namespace GpgME { + class Error; + class Key; +} + +namespace Kleo { + class DeleteJob; +} + +namespace Kleo { + + /** + @short A convenience class bundling together multiple DeleteJobs. + + To use a MultiDeleteJob, pass it a CryptoBackend implementation, + connect the progress() and result() signals to suitable slots and + then start the delete with a call to start(). This call might + fail, in which case the MultiDeleteJob instance will have scheduled + it's own destruction with a call to QObject::deleteLater(). + + After result() is emitted, the MultiDeleteJob will schedule it's own + destruction by calling QObject::deleteLater(). + */ + class KDE_EXPORT MultiDeleteJob : public Job { + Q_OBJECT + public: + MultiDeleteJob( const CryptoBackend::Protocol * protocol ); + ~MultiDeleteJob(); + + /** + Starts the delete operation. \a keys is the list of keys to + delete, \a allowSecretKeyDeletion specifies if a key may also + be deleted if the secret key part is available, too. + */ + GpgME::Error start( const std::vector & keys, bool allowSecretKeyDeletion=false ); + + signals: + void result( const GpgME::Error & result, const GpgME::Key & errorKey ); + + private slots: + void slotResult( const GpgME::Error & ); + /*! \reimp from Job */ + void slotCancel(); + + private: + GpgME::Error startAJob(); + + private: + const CryptoBackend::Protocol * mProtocol; + QGuardedPtr mJob; + std::vector mKeys; + std::vector::const_iterator mIt; + bool mAllowSecretKeyDeletion; + }; + +} + +#endif // __KLEO_MULTIDELETEJOB_H__ diff --git a/lib/kleo/cryptobackend.cpp b/lib/kleo/oidmap.h similarity index 61% copy from lib/kleo/cryptobackend.cpp copy to lib/kleo/oidmap.h index 6da71bc9e..596296332 100644 --- a/lib/kleo/cryptobackend.cpp +++ b/lib/kleo/oidmap.h @@ -1,36 +1,57 @@ /* - kleo/cryptobackend.cpp + oidmap.h This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#include "cryptobackend.h" +#ifndef __KLEO_OIDMAP_H__ +#define __KLEO_OIDMAP_H__ -const char Kleo::CryptoBackend::OpenPGP[] = "OpenPGP"; -const char Kleo::CryptoBackend::SMIME[] = "SMIME"; +static struct { + const char * name; + const char * oid; +} oidmap[] = { + // keep them ordered by oid: + { "SP", "ST" }, // hack to show the Sphinx-required/desired SP for + // StateOrProvince, otherwise known as ST or even S + { "NameDistinguisher", "0.2.262.1.10.7.20" }, + { "EMAIL", "1.2.840.113549.1.9.1" }, + { "SN", "2.5.4.4" }, + { "SerialNumber", "2.5.4.5" }, + { "T", "2.5.4.12" }, + { "D", "2.5.4.13" }, + { "BC", "2.5.4.15" }, + { "ADDR", "2.5.4.16" }, + { "PC", "2.5.4.17" }, + { "GN", "2.5.4.42" }, + { "Pseudo", "2.5.4.65" }, +}; +static const unsigned int numOidMaps = sizeof oidmap / sizeof *oidmap; + +#endif // __KLEO_OIDMAP_H__ diff --git a/lib/kleo/specialjob.h b/lib/kleo/refreshkeysjob.h similarity index 50% copy from lib/kleo/specialjob.h copy to lib/kleo/refreshkeysjob.h index 106257428..dcf9cd516 100644 --- a/lib/kleo/specialjob.h +++ b/lib/kleo/refreshkeysjob.h @@ -1,86 +1,90 @@ /* - specialjob.h + refreshkeysjob.h This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#ifndef __KLEO_SPECIALJOB_H__ -#define __KLEO_SPECIALJOB_H__ +#ifndef __KLEO_REFRESHKEYSJOB_H__ +#define __KLEO_REFRESHKEYSJOB_H__ #include "job.h" +#include + namespace GpgME { class Error; + class Key; } +class QStringList; + namespace Kleo { /** - @short An abstract base class for protocol-specific jobs + @short An abstract base class for asynchronous key refreshers. - To use a SpecialJob, first obtain an instance from the - CryptoBackend implementation, connect progress() and result() - signals to suitable slots and then start the job with a call to - start(). This call might fail, in which case the SpecialJob - instance will have schedules its own destruction with a call to - QObject::deleteLater(). + To use a RefreshKeysJob, first obtain an instance from the + CryptoBackend implementation, connect the progress() and result() + signals to suitable slots and then start the key refresh with a + call to start(). This call might fail, in which case the + RefreshKeysJob instance will have scheduled its own destruction + with a call to QObject::deleteLater(). - After result() is emitted, the SpecialJob will schedule its own + After result() is emitted, the KeyListJob will schedule it's own destruction by calling QObject::deleteLater(). - - Parameters are set using the Qt property system. More general, or - constructor parameters are given in the call to - Kleo::CryptoBackend::Protocol::specialJob(). - - The result is made available through the result signal, and - through the read-only result property, the latter of which needs - to be defined in each SpecialJob subclass. */ - class SpecialJob : public Job { + class RefreshKeysJob : public Job { Q_OBJECT protected: - SpecialJob( QObject * parent, const char * name ); + RefreshKeysJob( QObject * parent, const char * name ); public: - ~SpecialJob(); - - /** - Starts the special operation. + ~RefreshKeysJob(); + + /** + Starts the keylist operation. \a pattern is a list of patterns + used to restrict the list of keys returned. Empty patterns are + ignored. If \a pattern is empty or contains only empty strings, + all keys are returned (however, the backend is free to truncate + the result and should do so; when this happens, it will be + reported by the reult object). + + If \a secretOnly is true, only keys for which the secret key is + also available are returned. Use this if you need to select a + key for signing. */ - virtual GpgME::Error start() = 0; - - virtual GpgME::Error exec() = 0; + virtual GpgME::Error start( const QStringList & patterns ) = 0; signals: - void result( const GpgME::Error & result, const QVariant & data ); + void result( const GpgME::Error & error ); }; } -#endif // __KLEO_SPECIALJOB_H__ +#endif // __KLEO_REFRESHKEYSJOB_H__ diff --git a/lib/kleo/signencryptjob.h b/lib/kleo/signencryptjob.h new file mode 100644 index 000000000..42d3a179f --- /dev/null +++ b/lib/kleo/signencryptjob.h @@ -0,0 +1,103 @@ +/* + signencryptjob.h + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifndef __KLEO_SIGNENCRYPTJOB_H__ +#define __KLEO_SIGNENCRYPTJOB_H__ + +#include // for Context::SignatureMode (or should + // we roll our own enum here?) +#include "job.h" +#include + +#include +#include + +namespace GpgME { + class Error; + class Key; + class SigningResult; + class EncryptionResult; +} + + +namespace Kleo { + + /** + @short An abstract base class for asynchronous combined signing and encrypting + + To use a SignEncryptJob, first obtain an instance from the + CryptoBackend implementation, connect the progress() and result() + signals to suitable slots and then start the operation with a + call to start(). This call might fail, in which case the + SignEncryptJob instance will have scheduled it's own destruction + with a call to QObject::deleteLater(). + + After result() is emitted, the SignEncryptJob will schedule it's + own destruction by calling QObject::deleteLater(). + */ + class SignEncryptJob : public Job { + Q_OBJECT + protected: + SignEncryptJob( QObject * parent, const char * name ); + public: + ~SignEncryptJob(); + + /** + Starts the combined signing and encrypting operation. \a signers + is the list of keys to sign \a plainText with. \a recipients is + a list of keys to encrypt the signed \a plainText to. In both + lists, empty (null) keys are ignored. + + If \a alwaysTrust is true, validity checking for the + \em recipient keys will not be performed, but full validity + assumed for all \em recipient keys without further checks. + */ + virtual GpgME::Error start( const std::vector & signers, + const std::vector & recipients, + const QByteArray & plainText, + bool alwaysTrust=false ) = 0; + + virtual std::pair + exec( const std::vector & signers, + const std::vector & recipients, + const QByteArray & plainText, + bool alwaysTrust, QByteArray & cipherText ) = 0; + + signals: + void result( const GpgME::SigningResult & signingresult, + const GpgME::EncryptionResult & encryptionresult, + const QByteArray & cipherText ); + }; + +} + +#endif // __KLEO_SIGNENCRYPTJOB_H__ diff --git a/lib/kleo/specialjob.h b/lib/kleo/signjob.h similarity index 52% copy from lib/kleo/specialjob.h copy to lib/kleo/signjob.h index 106257428..17ea3d947 100644 --- a/lib/kleo/specialjob.h +++ b/lib/kleo/signjob.h @@ -1,86 +1,90 @@ /* - specialjob.h + signjob.h This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#ifndef __KLEO_SPECIALJOB_H__ -#define __KLEO_SPECIALJOB_H__ +#ifndef __KLEO_SIGNJOB_H__ +#define __KLEO_SIGNJOB_H__ +#include // for Context::SignatureMode (or should + // we roll our own enum here?) #include "job.h" +#include + +#include namespace GpgME { class Error; + class Key; + class SigningResult; } + namespace Kleo { /** - @short An abstract base class for protocol-specific jobs + @short An abstract base class for asynchronous signing - To use a SpecialJob, first obtain an instance from the - CryptoBackend implementation, connect progress() and result() - signals to suitable slots and then start the job with a call to - start(). This call might fail, in which case the SpecialJob - instance will have schedules its own destruction with a call to + To use a SignJob, first obtain an instance from the CryptoBackend + implementation, connect the progress() and result() signals to + suitable slots and then start the signing with a call to + start(). This call might fail, in which case the SignJob instance + will have scheduled it's own destruction with a call to QObject::deleteLater(). - After result() is emitted, the SpecialJob will schedule its own + After result() is emitted, the SignJob will schedule it's own destruction by calling QObject::deleteLater(). - - Parameters are set using the Qt property system. More general, or - constructor parameters are given in the call to - Kleo::CryptoBackend::Protocol::specialJob(). - - The result is made available through the result signal, and - through the read-only result property, the latter of which needs - to be defined in each SpecialJob subclass. */ - class SpecialJob : public Job { + class SignJob : public Job { Q_OBJECT protected: - SpecialJob( QObject * parent, const char * name ); - + SignJob( QObject * parent, const char * name ); public: - ~SpecialJob(); + ~SignJob(); /** - Starts the special operation. + Starts the signing operation. \a signers is the list of keys to + sign \a plainText with. Empty (null) keys are ignored. */ - virtual GpgME::Error start() = 0; - - virtual GpgME::Error exec() = 0; + virtual GpgME::Error start( const std::vector & signers, + const QByteArray & plainText, + GpgME::Context::SignatureMode mode ) = 0; + virtual GpgME::SigningResult exec( const std::vector & signers, + const QByteArray & plainText, + GpgME::Context::SignatureMode mode, + QByteArray & signature ) = 0; signals: - void result( const GpgME::Error & result, const QVariant & data ); + void result( const GpgME::SigningResult & result, const QByteArray & signature ); }; } -#endif // __KLEO_SPECIALJOB_H__ +#endif // __KLEO_SIGNJOB_H__ diff --git a/lib/kleo/specialjob.h b/lib/kleo/specialjob.h index 106257428..e7280b0a5 100644 --- a/lib/kleo/specialjob.h +++ b/lib/kleo/specialjob.h @@ -1,86 +1,86 @@ /* specialjob.h This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifndef __KLEO_SPECIALJOB_H__ #define __KLEO_SPECIALJOB_H__ #include "job.h" namespace GpgME { class Error; } namespace Kleo { /** @short An abstract base class for protocol-specific jobs To use a SpecialJob, first obtain an instance from the CryptoBackend implementation, connect progress() and result() signals to suitable slots and then start the job with a call to start(). This call might fail, in which case the SpecialJob instance will have schedules its own destruction with a call to QObject::deleteLater(). After result() is emitted, the SpecialJob will schedule its own destruction by calling QObject::deleteLater(). Parameters are set using the Qt property system. More general, or constructor parameters are given in the call to Kleo::CryptoBackend::Protocol::specialJob(). The result is made available through the result signal, and through the read-only result property, the latter of which needs to be defined in each SpecialJob subclass. */ class SpecialJob : public Job { Q_OBJECT protected: SpecialJob( QObject * parent, const char * name ); public: ~SpecialJob(); /** Starts the special operation. */ virtual GpgME::Error start() = 0; virtual GpgME::Error exec() = 0; signals: void result( const GpgME::Error & result, const QVariant & data ); }; } #endif // __KLEO_SPECIALJOB_H__ diff --git a/lib/kleo/specialjob.h b/lib/kleo/verifydetachedjob.h similarity index 51% copy from lib/kleo/specialjob.h copy to lib/kleo/verifydetachedjob.h index 106257428..f50fda546 100644 --- a/lib/kleo/specialjob.h +++ b/lib/kleo/verifydetachedjob.h @@ -1,86 +1,86 @@ /* - specialjob.h + verifydetachedjob.h This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#ifndef __KLEO_SPECIALJOB_H__ -#define __KLEO_SPECIALJOB_H__ +#ifndef __KLEO_VERIFYDETACHEDJOB_H__ +#define __KLEO_VERIFYDETACHEDJOB_H__ #include "job.h" +#include + namespace GpgME { class Error; + class Key; + class VerificationResult; } + namespace Kleo { /** - @short An abstract base class for protocol-specific jobs - - To use a SpecialJob, first obtain an instance from the - CryptoBackend implementation, connect progress() and result() - signals to suitable slots and then start the job with a call to - start(). This call might fail, in which case the SpecialJob - instance will have schedules its own destruction with a call to - QObject::deleteLater(). + @short An abstract base class for asynchronous verification of detached signatures - After result() is emitted, the SpecialJob will schedule its own - destruction by calling QObject::deleteLater(). + To use a VerifyDetachedJob, first obtain an instance from the + CryptoBackend implementation, connect the progress() and result() + signals to suitable slots and then start the verification with a + call to start(). This call might fail, in which case the + VerifyDetachedJob instance will have scheduled it's own + destruction with a call to QObject::deleteLater(). - Parameters are set using the Qt property system. More general, or - constructor parameters are given in the call to - Kleo::CryptoBackend::Protocol::specialJob(). - - The result is made available through the result signal, and - through the read-only result property, the latter of which needs - to be defined in each SpecialJob subclass. + After result() is emitted, the VerifyDetachedJob will schedule + it's own destruction by calling QObject::deleteLater(). */ - class SpecialJob : public Job { + class VerifyDetachedJob : public Job { Q_OBJECT protected: - SpecialJob( QObject * parent, const char * name ); - + VerifyDetachedJob( QObject * parent, const char * name ); public: - ~SpecialJob(); + ~VerifyDetachedJob(); /** - Starts the special operation. + Starts the verification operation. \a signature contains the + signature data, while \a signedData contains the data over + which the signature was made. */ - virtual GpgME::Error start() = 0; + virtual GpgME::Error start( const QByteArray & signature, + const QByteArray & signedData ) = 0; - virtual GpgME::Error exec() = 0; + virtual GpgME::VerificationResult exec( const QByteArray & signature, + const QByteArray & signedData ) = 0; signals: - void result( const GpgME::Error & result, const QVariant & data ); + void result( const GpgME::VerificationResult & result ); }; } -#endif // __KLEO_SPECIALJOB_H__ +#endif // __KLEO_VERIFYDETACHEDJOB_H__ diff --git a/lib/kleo/specialjob.h b/lib/kleo/verifyopaquejob.h similarity index 51% copy from lib/kleo/specialjob.h copy to lib/kleo/verifyopaquejob.h index 106257428..b38b18de1 100644 --- a/lib/kleo/specialjob.h +++ b/lib/kleo/verifyopaquejob.h @@ -1,86 +1,85 @@ /* - specialjob.h + verifyopaquejob.h This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#ifndef __KLEO_SPECIALJOB_H__ -#define __KLEO_SPECIALJOB_H__ +#ifndef __KLEO_VERIFYOPAQUEJOB_H__ +#define __KLEO_VERIFYOPAQUEJOB_H__ #include "job.h" +#include + namespace GpgME { class Error; + class Key; + class VerificationResult; } + namespace Kleo { /** - @short An abstract base class for protocol-specific jobs - - To use a SpecialJob, first obtain an instance from the - CryptoBackend implementation, connect progress() and result() - signals to suitable slots and then start the job with a call to - start(). This call might fail, in which case the SpecialJob - instance will have schedules its own destruction with a call to - QObject::deleteLater(). + @short An abstract base class for asynchronous verification of opaque signatures - After result() is emitted, the SpecialJob will schedule its own - destruction by calling QObject::deleteLater(). + To use a VerifyOpaqueJob, first obtain an instance from the + CryptoBackend implementation, connect the progress() and result() + signals to suitable slots and then start the verification with a + call to start(). This call might fail, in which case the + VerifyOpaqueJob instance will have scheduled it's own + destruction with a call to QObject::deleteLater(). - Parameters are set using the Qt property system. More general, or - constructor parameters are given in the call to - Kleo::CryptoBackend::Protocol::specialJob(). - - The result is made available through the result signal, and - through the read-only result property, the latter of which needs - to be defined in each SpecialJob subclass. + After result() is emitted, the VerifyOpaqueJob will schedule + it's own destruction by calling QObject::deleteLater(). */ - class SpecialJob : public Job { + class VerifyOpaqueJob : public Job { Q_OBJECT protected: - SpecialJob( QObject * parent, const char * name ); - + VerifyOpaqueJob( QObject * parent, const char * name ); public: - ~SpecialJob(); + ~VerifyOpaqueJob(); /** - Starts the special operation. + Starts the verification operation. \a signature contains the + signature data, while \a signedData contains the data over + which the signature was made. */ - virtual GpgME::Error start() = 0; + virtual GpgME::Error start( const QByteArray & signedData ) = 0; - virtual GpgME::Error exec() = 0; + /** Synchronous version of @ref start */ + virtual GpgME::VerificationResult exec( const QByteArray & signedData, QByteArray & plainText ) = 0; signals: - void result( const GpgME::Error & result, const QVariant & data ); + void result( const GpgME::VerificationResult & result, const QByteArray & plainText ); }; } -#endif // __KLEO_SPECIALJOB_H__ +#endif // __KLEO_VERIFYOPAQUEJOB_H__ diff --git a/lib/backends/chiasmus/chiasmuslibrary.h b/lib/tests/gnupgviewer.h similarity index 57% copy from lib/backends/chiasmus/chiasmuslibrary.h copy to lib/tests/gnupgviewer.h index 1759b4fc7..efba1760b 100644 --- a/lib/backends/chiasmus/chiasmuslibrary.h +++ b/lib/tests/gnupgviewer.h @@ -1,68 +1,64 @@ -/* -*- mode: C++; c-file-style: "gnu" -*- - chiasmuslibrary.h +/* + gnupgviewer.h - This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + This file is part of libkleopatra's test suite. + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ +#ifndef __KLEO_TESTS_GNUPGVIEWER_H__ +#define __KLEO_TESTS_GNUPGVIEWER_H__ -#ifndef __KLEO_CHIASMUSLIBRARY_H__ -#define __KLEO_CHIASMUSLIBRARY_H__ - -#include -#include - -class KLibrary; +#include +#include namespace Kleo { + class GnuPGProcessBase; +} +class KProcess; +class QStringList; - /** - @short small helper class to load xia.o through xia.so and make - the functionality available. - */ - class ChiasmusLibrary { - ChiasmusLibrary(); - ~ChiasmusLibrary(); - public: - static const ChiasmusLibrary * instance(); - static void deleteInstance(); - - int perform( const QValueVector & args ) const; - private: - typedef int ( *main_func )( int, char** ); - main_func chiasmus( QString * reason=0 ) const; +class GnuPGViewer : public QTextEdit { + Q_OBJECT +public: + GnuPGViewer( QWidget * parent=0, const char * name=0 ); + ~GnuPGViewer(); - private: - static ChiasmusLibrary * self; - mutable KLibrary * mXiaLibrary; - }; + void setProcess( Kleo::GnuPGProcessBase * process ); -} +private slots: + void slotStdout( KProcess *, char *, int ); + void slotStderr( KProcess *, char *, int ); + void slotStatus( Kleo::GnuPGProcessBase *, const QString &, const QStringList & ); + void slotProcessExited( KProcess * ); +private: + Kleo::GnuPGProcessBase * mProcess; + QString mLastStdout, mLastStderr, mLastStatus; +}; -#endif // __KLEO_CHIASMUSLIBRARY_H__ +#endif // __KLEO_TESTS_GNUPGVIEWER_H__ diff --git a/lib/tests/test_cryptoconfig.cpp b/lib/tests/test_cryptoconfig.cpp index 2c3ca72fe..fab91cff1 100644 --- a/lib/tests/test_cryptoconfig.cpp +++ b/lib/tests/test_cryptoconfig.cpp @@ -1,365 +1,365 @@ /* test_cryptoconfig.cpp This file is part of libkleopatra's test suite. Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2, as published by the Free Software Foundation. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #include #include #include #include #include using namespace std; #include #include int main( int argc, char** argv ) { KAboutData aboutData( "test_cryptoconfig", "CryptoConfig Test", "0.1" ); KCmdLineArgs::init( argc, argv, &aboutData ); KApplication app( false, false ); Kleo::CryptoConfig * config = new QGpgMECryptoConfig(); // Dynamic querying of the options cout << "Components:" << endl; QStringList components = config->componentList(); for( QStringList::Iterator compit = components.begin(); compit != components.end(); ++compit ) { cout << "Component " << (*compit).local8Bit() << ":" << endl; const Kleo::CryptoConfigComponent* comp = config->component( *compit ); assert( comp ); QStringList groups = comp->groupList(); for( QStringList::Iterator groupit = groups.begin(); groupit != groups.end(); ++groupit ) { const Kleo::CryptoConfigGroup* group = comp->group( *groupit ); assert( group ); cout << " Group " << (*groupit).local8Bit() << ": descr=\"" << group->description().local8Bit() << "\"" << " level=" << group->level() << endl; QStringList entries = group->entryList(); for( QStringList::Iterator entryit = entries.begin(); entryit != entries.end(); ++entryit ) { const Kleo::CryptoConfigEntry* entry = group->entry( *entryit ); assert( entry ); cout << " Entry " << (*entryit).local8Bit() << ":" << " descr=\"" << entry->description().local8Bit() << "\"" << " " << ( entry->isSet() ? "is set" : "is not set" ); if ( !entry->isList() ) switch( entry->argType() ) { case Kleo::CryptoConfigEntry::ArgType_None: break; case Kleo::CryptoConfigEntry::ArgType_Int: cout << " int value=" << entry->intValue(); break; case Kleo::CryptoConfigEntry::ArgType_UInt: cout << " uint value=" << entry->uintValue(); break; case Kleo::CryptoConfigEntry::ArgType_LDAPURL: case Kleo::CryptoConfigEntry::ArgType_URL: cout << " URL value=" << entry->urlValue().prettyURL().local8Bit(); // fallthrough case Kleo::CryptoConfigEntry::ArgType_Path: // fallthrough case Kleo::CryptoConfigEntry::ArgType_DirPath: // fallthrough case Kleo::CryptoConfigEntry::ArgType_String: cout << " string value=" << entry->stringValue().local8Bit(); break; } else // lists { switch( entry->argType() ) { case Kleo::CryptoConfigEntry::ArgType_None: { cout << " set " << entry->numberOfTimesSet() << " times"; break; } case Kleo::CryptoConfigEntry::ArgType_Int: { assert( entry->isOptional() ); // empty lists must be allowed (see issue121) QValueList lst = entry->intValueList(); QString str; for( QValueList::Iterator it = lst.begin(); it != lst.end(); ++it ) { str += QString::number( *it ); } cout << " int values=" << str.local8Bit(); break; } case Kleo::CryptoConfigEntry::ArgType_UInt: { assert( entry->isOptional() ); // empty lists must be allowed (see issue121) QValueList lst = entry->uintValueList(); QString str; for( QValueList::Iterator it = lst.begin(); it != lst.end(); ++it ) { str += QString::number( *it ); } cout << " uint values=" << str.local8Bit(); break; } case Kleo::CryptoConfigEntry::ArgType_LDAPURL: case Kleo::CryptoConfigEntry::ArgType_URL: { assert( entry->isOptional() ); // empty lists must be allowed (see issue121) KURL::List urls = entry->urlValueList(); cout << " url values=" << urls.toStringList().join(" ").local8Bit() << "\n "; } // fallthrough case Kleo::CryptoConfigEntry::ArgType_Path: // fallthrough case Kleo::CryptoConfigEntry::ArgType_DirPath: // fallthrough case Kleo::CryptoConfigEntry::ArgType_String: { assert( entry->isOptional() ); // empty lists must be allowed (see issue121) QStringList lst = entry->stringValueList(); cout << " string values=" << lst.join(" ").local8Bit(); break; } } } cout << endl; } // ... } } { // Static querying of a single boolean option static const char* s_groupName = "Monitor"; static const char* s_entryName = "quiet"; Kleo::CryptoConfigEntry* entry = config->entry( "dirmngr", s_groupName, s_entryName ); if ( entry ) { assert( entry->argType() == Kleo::CryptoConfigEntry::ArgType_None ); bool val = entry->boolValue(); cout << "quiet option initially: " << ( val ? "is set" : "is not set" ) << endl; entry->setBoolValue( !val ); assert( entry->isDirty() ); config->sync( true ); // Clear cached values! config->clear(); // Check new value Kleo::CryptoConfigEntry* entry = config->entry( "dirmngr", s_groupName, s_entryName ); assert( entry ); assert( entry->argType() == Kleo::CryptoConfigEntry::ArgType_None ); cout << "quiet option now: " << ( val ? "is set" : "is not set" ) << endl; assert( entry->boolValue() == !val ); // Set to default entry->resetToDefault(); assert( entry->boolValue() == false ); // that's the default assert( entry->isDirty() ); assert( !entry->isSet() ); config->sync( true ); config->clear(); // Check value entry = config->entry( "dirmngr", s_groupName, s_entryName ); assert( !entry->isDirty() ); assert( !entry->isSet() ); cout << "quiet option reset to default: " << ( entry->boolValue() ? "is set" : "is not set" ) << endl; assert( entry->boolValue() == false ); // Reset old value entry->setBoolValue( val ); assert( entry->isDirty() ); config->sync( true ); cout << "quiet option reset to initial: " << ( val ? "is set" : "is not set" ) << endl; } else cout << "Entry 'dirmngr/" << s_groupName << "/" << s_entryName << "' not found" << endl; } { // Static querying and setting of a single int option static const char* s_groupName = "LDAP"; static const char* s_entryName = "ldaptimeout"; Kleo::CryptoConfigEntry* entry = config->entry( "dirmngr", s_groupName, s_entryName ); if ( entry ) { assert( entry->argType() == Kleo::CryptoConfigEntry::ArgType_UInt ); uint val = entry->uintValue(); cout << "LDAP timeout initially: " << val << " seconds." << endl; // Test setting the option directly, then querying again //system( "echo 'ldaptimeout:0:101' | gpgconf --change-options dirmngr" ); // Now let's do it with the C++ API instead entry->setUIntValue( 101 ); assert( entry->isDirty() ); config->sync( true ); // Clear cached values! config->clear(); // Check new value Kleo::CryptoConfigEntry* entry = config->entry( "dirmngr", s_groupName, s_entryName ); assert( entry ); assert( entry->argType() == Kleo::CryptoConfigEntry::ArgType_UInt ); cout << "LDAP timeout now: " << entry->uintValue() << " seconds." << endl; assert( entry->uintValue() == 101 ); // Set to default entry->resetToDefault(); assert( entry->uintValue() == 100 ); assert( entry->isDirty() ); assert( !entry->isSet() ); config->sync( true ); config->clear(); // Check value entry = config->entry( "dirmngr", s_groupName, s_entryName ); assert( !entry->isDirty() ); assert( !entry->isSet() ); cout << "LDAP timeout reset to default, " << entry->uintValue() << " seconds." << endl; assert( entry->uintValue() == 100 ); // Reset old value entry->setUIntValue( val ); assert( entry->isDirty() ); config->sync( true ); cout << "LDAP timeout reset to initial " << val << " seconds." << endl; } else cout << "Entry 'dirmngr/" << s_groupName << "/" << s_entryName << "' not found" << endl; } { // Static querying and setting of a single string option static const char* s_groupName = "Debug"; static const char* s_entryName = "log-file"; Kleo::CryptoConfigEntry* entry = config->entry( "dirmngr", s_groupName, s_entryName ); if ( entry ) { assert( entry->argType() == Kleo::CryptoConfigEntry::ArgType_Path ); QString val = entry->stringValue(); cout << "Log-file initially: " << val.local8Bit() << endl; // Test setting the option, sync'ing, then querying again entry->setStringValue( "/tmp/test:%e5ä" ); assert( entry->isDirty() ); config->sync( true ); // Let's see how it prints it system( "gpgconf --list-options dirmngr | grep log-file" ); // Clear cached values! config->clear(); // Check new value Kleo::CryptoConfigEntry* entry = config->entry( "dirmngr", s_groupName, s_entryName ); assert( entry ); assert( entry->argType() == Kleo::CryptoConfigEntry::ArgType_Path ); cout << "Log-file now: " << entry->stringValue().local8Bit() << endl; assert( entry->stringValue() == "/tmp/test:%e5ä" ); // (or even with %e5 decoded) // Reset old value #if 0 QString arg( val ); if ( !arg.isEmpty() ) arg.prepend( '"' ); QCString sys; sys.sprintf( "echo 'log-file:%s' | gpgconf --change-options dirmngr", arg.local8Bit().data() ); system( sys.data() ); #endif entry->setStringValue( val ); assert( entry->isDirty() ); config->sync( true ); cout << "Log-file reset to initial " << val.local8Bit() << endl; } else cout << "Entry 'dirmngr/" << s_groupName << "/" << s_entryName << "' not found" << endl; } { // Static querying and setting of the LDAP URL list option static const char* s_groupName = "LDAP"; static const char* s_entryName = "LDAP Server"; Kleo::CryptoConfigEntry* entry = config->entry( "dirmngr", s_groupName, s_entryName ); if ( entry ) { assert( entry->argType() == Kleo::CryptoConfigEntry::ArgType_LDAPURL ); assert( entry->isList() ); KURL::List val = entry->urlValueList(); cout << "URL list initially: " << val.toStringList().join(", ").local8Bit() << endl; // Test setting the option, sync'ing, then querying again KURL::List lst; // We use non-empty paths to workaround a bug in KURL (kdelibs-3.2) lst << KURL( "ldap://a:389/?b" ); // Test with query containing a litteral ':' (KURL supports this) // and a ' ' (KURL will escape it, see issue119) lst << KURL( "ldap://foo:389/?a:b c" ); lst << KURL( "ldap://server:389/?a%3db,c=DE" ); // the query contains a litteral ',' //cout << " trying to set: " << lst.toStringList().join(", ").local8Bit() << endl; assert( lst[0].query() == "?b" ); assert( lst[1].query() == "?a:b%20c" ); // see, the space got escaped entry->setURLValueList( lst ); assert( entry->isDirty() ); config->sync( true ); // Let's see how it prints it system( "gpgconf --list-options dirmngr | grep 'LDAP Server'" ); // Clear cached values! config->clear(); // Check new value Kleo::CryptoConfigEntry* entry = config->entry( "dirmngr", s_groupName, s_entryName ); assert( entry ); assert( entry->argType() == Kleo::CryptoConfigEntry::ArgType_LDAPURL ); assert( entry->isList() ); // Get raw a:b:c:d:e form QStringList asStringList = entry->stringValueList(); assert( asStringList.count() == 3 ); cout << "asStringList[0]=" << asStringList[0].local8Bit() << endl; cout << "asStringList[1]=" << asStringList[1].local8Bit() << endl; cout << "asStringList[2]=" << asStringList[2].local8Bit() << endl; assert( asStringList[0] == "a:389:::b" ); assert( asStringList[1] == "foo:389:::a%3ab c" ); // the space must be decoded (issue119) assert( asStringList[2] == "server:389:::a=b,c=DE" ); // all decoded // Get KURL form KURL::List newlst = entry->urlValueList(); cout << "URL list now: " << newlst.toStringList().join(", ").local8Bit() << endl; assert( newlst.count() == 3 ); //cout << "newlst[0]=" << newlst[0].url().local8Bit() << endl; //cout << "lst[0]=" << lst[0].url().local8Bit() << endl; assert( newlst[0] == lst[0] ); assert( newlst[1] == lst[1] ); assert( newlst[2].url() == "ldap://server:389/?a=b,c=DE" ); // != lst[2] due to the encoded = // Reset old value entry->setURLValueList( val ); assert( entry->isDirty() ); config->sync( true ); cout << "URL list reset to initial: " << val.toStringList().join(", ").local8Bit() << endl; } else cout << "Entry 'dirmngr/" << s_groupName << "/" << s_entryName << "' not found" << endl; } cout << "Done." << endl; } diff --git a/lib/tests/test_gnupgprocessbase.cpp b/lib/tests/test_gnupgprocessbase.cpp new file mode 100644 index 000000000..37e961801 --- /dev/null +++ b/lib/tests/test_gnupgprocessbase.cpp @@ -0,0 +1,143 @@ +/* + gnupgviewer.cpp + + This file is part of libkleopatra's test suite. + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "gnupgviewer.h" + +#include + +#include +#include +#include +#include +#include + +#include + +GnuPGViewer::GnuPGViewer( QWidget * parent, const char * name ) + : QTextEdit( parent, name ), mProcess( 0 ) +{ + setTextFormat( LogText ); + setMaxLogLines( 10000 ); +} + +GnuPGViewer::~GnuPGViewer() { + if ( mProcess ) + mProcess->kill(); +} + +void GnuPGViewer::setProcess( Kleo::GnuPGProcessBase * process ) { + if ( !process ) + return; + mProcess = process; + connect( mProcess, SIGNAL(processExited(KProcess*)), + SLOT(slotProcessExited(KProcess*)) ); + connect( mProcess, SIGNAL(receivedStdout(KProcess*,char*,int)), + SLOT(slotStdout(KProcess*,char*,int)) ); + connect( mProcess, SIGNAL(receivedStderr(KProcess*,char*,int)), + SLOT(slotStderr(KProcess*,char*,int)) ); + connect( mProcess, SIGNAL(status(Kleo::GnuPGProcessBase*,const QString&,const QStringList&)), + SLOT(slotStatus(Kleo::GnuPGProcessBase*,const QString&,const QStringList&)) ); +} + +static QStringList split( char * buffer, int buflen, QString & old ) { + // when done right, this would need to use QTextCodec... + const QString str = old + QString::fromLocal8Bit( buffer, buflen ); + QStringList l = QStringList::split( '\n', str, true ); + if ( l.empty() ) + return l; + if ( str.endsWith( "\n" ) ) { + old = QString::null; + } else { + old = l.back(); + l.pop_back(); + } + return l; +} + +static QString escape( QString str ) { + return str.replace( '&', "&" ).replace( '<', "<" ).replace( '>', ">" ); +} + +void GnuPGViewer::slotStdout( KProcess *, char * buffer, int buflen ) { + const QStringList l = split( buffer, buflen, mLastStdout ); + for ( QStringList::const_iterator it = l.begin() ; it != l.end() ; ++it ) + append( "stdout: " + escape( *it ) ); +} + +void GnuPGViewer::slotStderr( KProcess *, char * buffer, int buflen ) { + const QStringList l = split( buffer, buflen, mLastStderr ); + for ( QStringList::const_iterator it = l.begin() ; it != l.end() ; ++it ) + append( "stderr: " + escape( *it ) + "" ); +} +void GnuPGViewer::slotStatus( Kleo::GnuPGProcessBase *, const QString & type, const QStringList & args ) { + append( "status: " + escape( type + ' ' + args.join( " " ) ) + "" ); +} +void GnuPGViewer::slotProcessExited( KProcess * proc ) { + if ( !proc ) + return; + if ( proc->normalExit() ) + append( QString( "Process exit: return code %1" ).arg ( proc->exitStatus() ) ); + else + append( "Process exit: killed" ); +} + +int main( int argc, char** argv ) { + if ( argc < 3 ) { + kdDebug() << "Need at least two arguments" << endl; + return 1; + } + KAboutData aboutData( "test_gnupgprocessbase", "GnuPGProcessBase Test", "0.1" ); + KCmdLineArgs::init( &aboutData ); + KApplication app; + + Kleo::GnuPGProcessBase gpg; + for ( int i = 1 ; i < argc ; ++i ) + gpg << argv[i]; + + gpg.setUseStatusFD( true ); + + GnuPGViewer * gv = new GnuPGViewer(); + gv->setProcess( &gpg ); + + app.setMainWidget( gv ); + gv->show(); + + gpg.start( KProcess::NotifyOnExit, KProcess::AllOutput ); + + return app.exec(); +} + +#include "gnupgviewer.moc" diff --git a/lib/tests/test_jobs.cpp b/lib/tests/test_jobs.cpp new file mode 100644 index 000000000..22d9136d4 --- /dev/null +++ b/lib/tests/test_jobs.cpp @@ -0,0 +1,108 @@ +/* + test_jobs.cpp + + This file is part of libkleopatra's test suite. + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +static const char * protocol = 0; + +static void testSign() +{ + const Kleo::CryptoBackend::Protocol * proto = protocol == "openpgp" ? Kleo::CryptoBackendFactory::instance()->openpgp() : Kleo::CryptoBackendFactory::instance()->smime() ; + assert( proto ); + + kdDebug() << "Using protocol " << proto->name() << endl; + + + std::vector signingKeys; + + std::auto_ptr listJob( proto->keyListJob( false, false, true ) ); // use validating keylisting + if ( listJob.get() ) { + // ##### Adjust this to your own identity + listJob->exec( "faure@kde.org", true /*secret*/, signingKeys ); + assert( !signingKeys.empty() ); + } else { + assert( 0 ); // job failed + } + + Kleo::SignJob* job = proto->signJob( true, true ); + + QCString cText = "Hallo Leute\n"; // like gpgme's t-sign.c + QByteArray plainText; + plainText.duplicate( cText.data(), cText.length() ); // hrmpf... + kdDebug() << k_funcinfo << "plainText=" << cText.data() << endl; + + kdDebug() << k_funcinfo << " signing with " << signingKeys[0].primaryFingerprint() << endl; + + QByteArray signature; + const GpgME::SigningResult res = + job->exec( signingKeys, plainText, GpgME::Context::Clearsigned, signature ); + if ( res.error().isCanceled() ) { + kdDebug() << "signing was canceled by user" << endl; + return; + } + if ( res.error() ) { + kdDebug() << "signing failed: " << res.error().asString() << endl; + return; + } + kdDebug() << k_funcinfo << "signing resulted in signature=" + << QCString( signature.data(), signature.size() + 1 ) << endl; +} + +int main( int argc, char** argv ) { + protocol = "openpgp"; + if ( argc == 2 ) { + protocol = argv[1]; + argc = 1; // hide from KDE + } + KAboutData aboutData( "test_jobs", "Signing Job Test", "0.1" ); + KCmdLineArgs::init( argc, argv, &aboutData ); + KApplication app; + + testSign(); +} diff --git a/lib/tests/test_keygen.cpp b/lib/tests/test_keygen.cpp new file mode 100644 index 000000000..9303b331c --- /dev/null +++ b/lib/tests/test_keygen.cpp @@ -0,0 +1,160 @@ +/* + test_keygen.cpp + + This file is part of libkleopatra's test suite. + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "test_keygen.h" + +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +static const char * keyParams[] = { + "Key-Type", "Key-Length", + "Subkey-Type", "Subkey-Length", + "Name-Real", "Name-Comment", "Name-Email", "Name-DN", + "Expire-Date", + "Passphrase" +}; +static const int numKeyParams = sizeof keyParams / sizeof *keyParams; + +static const char * protocol = 0; + +KeyGenerator::KeyGenerator( QWidget * parent, const char * name, WFlags ) + : KDialogBase( parent, name, true, "KeyGenerationJob test", + Close|User1, User1, true, KGuiItem( "Create" ) ) +{ + QWidget * w = new QWidget( this ); + setMainWidget( w ); + + QGridLayout * glay = new QGridLayout( w, numKeyParams+3, 2, marginHint(), spacingHint() ); + + int row = -1; + + ++row; + glay->addMultiCellWidget( new QLabel( "", w ), + row, row, 0, 1 ); + for ( int i = 0 ; i < numKeyParams ; ++i ) { + ++row; + glay->addWidget( new QLabel( keyParams[i], w ), row, 0 ); + glay->addWidget( mLineEdits[i] = new QLineEdit( w ), row, 1 ); + } + + ++row; + glay->addMultiCellWidget( new QLabel( "", w ), + row, row, 0, 1 ); + ++row; + glay->setRowStretch( row, 1 ); + glay->setColStretch( 1, 1 ); + + connect( this, SIGNAL(user1Clicked()), SLOT(slotStartKeyGeneration()) ); +} + +KeyGenerator::~KeyGenerator() {} + +void KeyGenerator::slotStartKeyGeneration() { + QString params = "\n"; + for ( int i = 0 ; i < numKeyParams ; ++i ) + if ( mLineEdits[i] && !mLineEdits[i]->text().stripWhiteSpace().isEmpty() ) + params += keyParams[i] + ( ": " + mLineEdits[i]->text().stripWhiteSpace() ) + '\n'; + params += "\n"; + + const Kleo::CryptoBackend::Protocol * proto = protocol == "openpgp" ? Kleo::CryptoBackendFactory::instance()->openpgp() : Kleo::CryptoBackendFactory::instance()->smime() ; + if ( !proto ) + proto = Kleo::CryptoBackendFactory::instance()->smime(); + assert( proto ); + + kdDebug() << "Using protocol " << proto->name() << endl; + + Kleo::KeyGenerationJob * job = proto->keyGenerationJob(); + assert( job ); + + connect( job, SIGNAL(result(const GpgME::KeyGenerationResult&,const QByteArray&)), + SLOT(slotResult(const GpgME::KeyGenerationResult&,const QByteArray&)) ); + + const GpgME::Error err = job->start( params ); + if ( err ) + showError( err ); + else + (void)new Kleo::ProgressDialog( job, "Generating key", this ); +} + +void KeyGenerator::showError( const GpgME::Error & err ) { + KMessageBox::error( this, "Could not start key generation: " + QString::fromLocal8Bit( err.asString() ), + "Key Generation Error" ); +} + +void KeyGenerator::slotResult( const GpgME::KeyGenerationResult & res, const QByteArray & keyData ) { + if ( res.error() ) + showError( res.error() ); + else + KMessageBox::information( this, QString("Key generated successfully, %1 bytes long").arg( keyData.size() ), + "Key Generation Finished" ); +} + +int main( int argc, char** argv ) { + if ( argc == 2 ) { + protocol = argv[1]; + argc = 1; // hide from KDE + } + KAboutData aboutData( "test_keygen", "KeyGenerationJob Test", "0.1" ); + KCmdLineArgs::init( argc, argv, &aboutData ); + KApplication app; + + KeyGenerator * keygen = new KeyGenerator( 0, "KeyGenerator top-level" ); + app.setMainWidget( keygen ); + keygen->show(); + + return app.exec(); +} + +#include "test_keygen.moc" diff --git a/lib/ui/cryptoconfigmodule.h b/lib/tests/test_keygen.h similarity index 55% copy from lib/ui/cryptoconfigmodule.h copy to lib/tests/test_keygen.h index df01d5d8a..0ba713823 100644 --- a/lib/ui/cryptoconfigmodule.h +++ b/lib/tests/test_keygen.h @@ -1,68 +1,62 @@ /* - cryptoconfigmodule.h + test_keygen.h - This file is part of libkleopatra - Copyright (c) 2004,2005 Klarälvdalens Datakonsult AB + This file is part of libkleopatra's test suite. + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2, as published by the Free Software Foundation. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#ifndef CRYPTOCONFIGMODULE_H -#define CRYPTOCONFIGMODULE_H +#ifndef __KLEO_TEST_KEYGEN_H__ +#define __KLEO_TEST_KEYGEN_H__ -#include +#include -#include +#include -namespace Kleo { - - class CryptoConfig; - class CryptoConfigComponentGUI; - - /** - * Crypto Config Module widget, dynamically generated from CryptoConfig - * It's a simple QWidget so that it can be embedded into a dialog or into a KCModule. - */ - class CryptoConfigModule : public KJanusWidget { - Q_OBJECT - public: - CryptoConfigModule( Kleo::CryptoConfig* config, QWidget * parent=0, const char * name=0 ); +namespace GpgME { + class Error; + class KeyGenerationResult; +} - void save(); - void reset(); // i.e. reload current settings, discarding user input - void defaults(); - void cancel(); +class QLineEdit; - signals: - void changed(); +class KeyGenerator : public KDialogBase { + Q_OBJECT +public: + KeyGenerator( QWidget * parent=0, const char * name=0, WFlags f=0 ); + ~KeyGenerator(); - private: - Kleo::CryptoConfig* mConfig; - QValueList mComponentGUIs; - }; +public slots: + void slotStartKeyGeneration(); + void slotResult( const GpgME::KeyGenerationResult & res, const QByteArray & keyData ); +private: + void showError( const GpgME::Error & err ); -} +private: + QLineEdit * mLineEdits[20]; +}; -#endif +#endif // __KLEO_TEST_KEYGEN_H__ diff --git a/lib/tests/test_keylister.cpp b/lib/tests/test_keylister.cpp new file mode 100644 index 000000000..9507221e7 --- /dev/null +++ b/lib/tests/test_keylister.cpp @@ -0,0 +1,146 @@ +/* + test_keylister.cpp + + This file is part of libkleopatra's test suite. + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#include + +#include "test_keylister.h" + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +namespace { + class TestColumnStrategy : public Kleo::KeyListView::ColumnStrategy { + public: + ~TestColumnStrategy() {} + QString title( int col ) const; + QString toolTip( const GpgME::Key & key, int col ) const; + QString text( const GpgME::Key & key, int col ) const; + }; + + QString TestColumnStrategy::title( int col ) const { + switch ( col ) { + case 0: return "Subject"; + case 1: return "EMail"; + case 2: return "Issuer"; + case 3: return "Serial"; + case 4: return "Protocol"; + case 5: return "Validity"; + default: return QString::null; + } + } + + QString TestColumnStrategy::toolTip( const GpgME::Key & key, int ) const { + return "Fingerprint: " + QString::fromUtf8( key.primaryFingerprint() ); + } + + QString TestColumnStrategy::text( const GpgME::Key & key, int col ) const { + if ( key.isNull() ) + return ""; + switch ( col ) { + case 0: return QString::fromUtf8( key.userID(0).id() ); + case 1: return QString::fromUtf8( key.userID(0).email() ); + case 2: return QString::fromUtf8( key.issuerName() ); + case 3: return key.issuerSerial(); + case 4: return key.protocolAsString(); + case 5: return QChar( key.userID(0).validityAsString() ); + default: return QString::null; + } + } +} + +CertListView::CertListView( QWidget * parent, const char * name, WFlags f ) + : Kleo::KeyListView( new TestColumnStrategy(), 0, parent, name, f ) +{ + setHierarchical( true ); + setRootIsDecorated( true ); +} + +void CertListView::slotResult( const GpgME::KeyListResult & result ) { + kdDebug() << "CertListView::slotResult()" << endl; + if ( result.isNull() ) + QMessageBox::information( this, "Key Listing Result", "KeyListResult is null!" ); + else if ( result.error() ) + QMessageBox::critical( this, "Key Listing Result", + QString("KeyListResult Error: %1").arg( result.error().asString() ) ); + else if ( result.isTruncated() ) + QMessageBox::information( this, "Key Listing Result", "KeyListResult is truncated!" ); + else + QMessageBox::information( this, "Key Listing Result", "Key listing successful" ); +} + +void CertListView::slotStart() { + kdDebug() << "CertListView::slotStart()" << endl; + Kleo::KeyListJob * job = Kleo::CryptoBackendFactory::instance()->smime()->keyListJob( false ); + assert( job ); + QObject::connect( job, SIGNAL(nextKey(const GpgME::Key&)), + this, SLOT(slotAddKey(const GpgME::Key&)) ); + QObject::connect( job, SIGNAL(result(const GpgME::KeyListResult&)), + this, SLOT(slotResult(const GpgME::KeyListResult&)) ); +#if 0 + QStringList l; + l << "Marc"; + job->start( l, false ); +#else + job->start( QStringList(), false ); +#endif +} + +int main( int argc, char** argv ) { + + KAboutData aboutData( "test_keylister", "KeyLister Test", "0.1" ); + KCmdLineArgs::init( argc, argv, &aboutData ); + KApplication app; + + CertListView * clv = new CertListView( 0, "CertListView top-level" ); + app.setMainWidget( clv ); + clv->show(); + + QTimer::singleShot( 5000, clv, SLOT(slotStart()) ); + + return app.exec(); +} + +#include "test_keylister.moc" diff --git a/lib/kleo/cryptobackend.cpp b/lib/tests/test_keylister.h similarity index 59% copy from lib/kleo/cryptobackend.cpp copy to lib/tests/test_keylister.h index 6da71bc9e..348ec262f 100644 --- a/lib/kleo/cryptobackend.cpp +++ b/lib/tests/test_keylister.h @@ -1,36 +1,52 @@ /* - kleo/cryptobackend.cpp + test_keylister.h - This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + This file is part of libkleopatra's test suite. + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. + modify it under the terms of the GNU General Public License, + version 2, as published by the Free Software Foundation. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#include "cryptobackend.h" +#ifndef __KLEO_TEST_KEYLISTER_H__ +#define __KLEO_TEST_KEYLISTER_H__ -const char Kleo::CryptoBackend::OpenPGP[] = "OpenPGP"; -const char Kleo::CryptoBackend::SMIME[] = "SMIME"; +#include + +namespace GpgME { + class Key; + class KeyListResult; +} + +class CertListView : public Kleo::KeyListView { + Q_OBJECT +public: + CertListView( QWidget * parent=0, const char * name=0, WFlags f=0 ); + +public slots: + void slotResult( const GpgME::KeyListResult & result ); + void slotStart(); +}; + +#endif // __KLEO_TEST_KEYLISTER_H__ diff --git a/lib/tests/test_keyselectiondialog.cpp b/lib/tests/test_keyselectiondialog.cpp new file mode 100644 index 000000000..e6c85fca0 --- /dev/null +++ b/lib/tests/test_keyselectiondialog.cpp @@ -0,0 +1,67 @@ +/* + test_keygen.cpp + + This file is part of libkleopatra's test suite. + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +int main( int argc, char ** argv ) { + KAboutData aboutData( "test_keyselectiondialog", "KeySelectionDialog Test", "0.1" ); + KCmdLineArgs::init( argc, argv, &aboutData ); + KApplication app; + + KGlobal::iconLoader()->addAppDir( "libkleopatra" ); + + Kleo::KeySelectionDialog dlg( "Kleo::KeySelectionDialog Test", + "Please select a key:", + std::vector(), + Kleo::KeySelectionDialog::AllKeys, true, true ); + + if ( dlg.exec() == QDialog::Accepted ) { + kdDebug() << "accepted; selected key: " << (dlg.selectedKey().userID(0).id() ? dlg.selectedKey().userID(0).id() : "") << "\nselected _keys_:" << endl; + for ( std::vector::const_iterator it = dlg.selectedKeys().begin() ; it != dlg.selectedKeys().end() ; ++it ) + kdDebug() << (it->userID(0).id() ? it->userID(0).id() : "") << endl; + } else { + kdDebug() << "rejected" << endl; + } + + return 0; +} diff --git a/kwatchgnupg/aboutdata.cpp b/lib/ui/adddirectoryservicedialogimpl.cpp similarity index 52% copy from kwatchgnupg/aboutdata.cpp copy to lib/ui/adddirectoryservicedialogimpl.cpp index 68c918e9d..973266b16 100644 --- a/kwatchgnupg/aboutdata.cpp +++ b/lib/ui/adddirectoryservicedialogimpl.cpp @@ -1,73 +1,63 @@ /* - aboutdata.cpp + adddirectoryservicedialogimpl.cpp This file is part of Kleopatra, the KDE keymanager - Copyright (c) 2004 Klar�vdalens Datakonsult AB + Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB Kleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Kleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#include "aboutdata.h" - -#include - -static const char kwatchgnupg_version[] = "1.0"; -static const char description[] = I18N_NOOP("GnuPG log viewer"); +#ifdef HAVE_CONFIG_H +#include +#endif -struct about_data { - const char * name; - const char * desc; - const char * email; - const char * web; -}; +#include "adddirectoryservicedialogimpl.h" -static const about_data authors[] = { - { "Steffen Hansen", I18N_NOOP("Original Author"), "hansen@kde.org", 0 }, -}; +#include +#include -#if 0 -// can't create zero size array - doesn't compile -static const about_data credits[] = { - // PENDING(steffen) add stuff -}; -#endif +/* + * Constructs a AddDirectoryServiceDialogImpl which is a child of 'parent', with the + * name 'name' and widget flags set to 'f' + * + * The dialog will by default be modeless, unless you set 'modal' to + * TRUE to construct a modal dialog. + */ +AddDirectoryServiceDialogImpl::AddDirectoryServiceDialogImpl( QWidget* parent, const char* name, bool modal, WFlags fl ) + : AddDirectoryServiceDialog( parent, name, modal, fl ) +{ + portED->setValidator( new QIntValidator( 0, 65535, portED ) ); +} -AboutData::AboutData() - : KAboutData( "kwatchgnupg", I18N_NOOP("KWatchGnuPG"), - kwatchgnupg_version, description, License_GPL, - "(c) 2004 Klar\xC3\xA4lvdalens Datakonsult AB\n" ) +/* + * Destroys the object and frees any allocated resources + */ +AddDirectoryServiceDialogImpl::~AddDirectoryServiceDialogImpl() { - using ::authors; - //using ::credits; - for ( unsigned int i = 0 ; i < sizeof authors / sizeof *authors ; ++i ) - addAuthor( authors[i].name, authors[i].desc, - authors[i].email, authors[i].web ); -#if 0 - for ( unsigned int i = 0 ; i < sizeof credits / sizeof *credits ; ++i ) - addCredit( credits[i].name, credits[i].desc, - credits[i].email, credits[i].web ); -#endif + // no need to delete child widgets, Qt does it all for us } + +#include "adddirectoryservicedialogimpl.moc" diff --git a/kwatchgnupg/aboutdata.cpp b/lib/ui/adddirectoryservicedialogimpl.h similarity index 52% copy from kwatchgnupg/aboutdata.cpp copy to lib/ui/adddirectoryservicedialogimpl.h index 68c918e9d..deee06439 100644 --- a/kwatchgnupg/aboutdata.cpp +++ b/lib/ui/adddirectoryservicedialogimpl.h @@ -1,73 +1,47 @@ /* - aboutdata.cpp + adddirectoryservicedialogimpl.h This file is part of Kleopatra, the KDE keymanager - Copyright (c) 2004 Klar�vdalens Datakonsult AB + Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB Kleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Kleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#include "aboutdata.h" +#ifndef ADDDIRECTORYSERVICEDIALOGIMPL_H +#define ADDDIRECTORYSERVICEDIALOGIMPL_H +#include "adddirectoryservicedialog.h" -#include - -static const char kwatchgnupg_version[] = "1.0"; -static const char description[] = I18N_NOOP("GnuPG log viewer"); - -struct about_data { - const char * name; - const char * desc; - const char * email; - const char * web; -}; +class AddDirectoryServiceDialogImpl : public AddDirectoryServiceDialog +{ + Q_OBJECT -static const about_data authors[] = { - { "Steffen Hansen", I18N_NOOP("Original Author"), "hansen@kde.org", 0 }, -}; +public: + AddDirectoryServiceDialogImpl( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~AddDirectoryServiceDialogImpl(); -#if 0 -// can't create zero size array - doesn't compile -static const about_data credits[] = { - // PENDING(steffen) add stuff }; -#endif -AboutData::AboutData() - : KAboutData( "kwatchgnupg", I18N_NOOP("KWatchGnuPG"), - kwatchgnupg_version, description, License_GPL, - "(c) 2004 Klar\xC3\xA4lvdalens Datakonsult AB\n" ) -{ - using ::authors; - //using ::credits; - for ( unsigned int i = 0 ; i < sizeof authors / sizeof *authors ; ++i ) - addAuthor( authors[i].name, authors[i].desc, - authors[i].email, authors[i].web ); -#if 0 - for ( unsigned int i = 0 ; i < sizeof credits / sizeof *credits ; ++i ) - addCredit( credits[i].name, credits[i].desc, - credits[i].email, credits[i].web ); -#endif -} +#endif // ADDDIRECTORYSERVICEDIALOGIMPL_H diff --git a/lib/ui/backendconfigwidget.cpp b/lib/ui/backendconfigwidget.cpp index 11a5df66f..c40890a43 100644 --- a/lib/ui/backendconfigwidget.cpp +++ b/lib/ui/backendconfigwidget.cpp @@ -1,323 +1,323 @@ /* -*- c++ -*- backendconfigwidget.cpp This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2002,2004,2005 Klarälvdalens Datakonsult AB Copyright (c) 2002,2003 Marc Mutz Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifdef HAVE_CONFIG_H #include #endif #include "backendconfigwidget.h" #include "cryptoconfigdialog.h" #include "kleo/cryptobackendfactory.h" #include "ui/keylistview.h" // for lvi_cast<> #include #include #include #include #include #include #include #include #include #include #include #include namespace Kleo { class BackendListView; } class Kleo::BackendConfigWidget::Private { public: Kleo::BackendListView * listView; QPushButton * configureButton; QPushButton * rescanButton; Kleo::CryptoBackendFactory * backendFactory; }; namespace Kleo { class BackendListViewItem; class ProtocolCheckListItem; } class Kleo::BackendListView : public KListView { public: BackendListView( BackendConfigWidget* parent, const char* name = 0 ) : KListView( parent, name ) {} /// return backend for currently selected (/current) item. Used by Configure button. const Kleo::CryptoBackend* currentBackend() const; /// return which protocol implementation was chosen (checked) for each type (used when saving) const Kleo::CryptoBackend* chosenBackend( const char * protocol ); /// deselect all except one for a given protocol type (radiobutton-like exclusivity) void deselectAll( const char * protocol, QCheckListItem* except ); void emitChanged() { static_cast( parentWidget() )->emitChanged( true ); } }; // Toplevel listviewitem for a given backend (e.g. "GpgME", "Kgpg/gpg v2") class Kleo::BackendListViewItem : public QListViewItem { public: BackendListViewItem( KListView* lv, QListViewItem *prev, const CryptoBackend *cryptoBackend ) : QListViewItem( lv, prev, cryptoBackend->displayName() ), mCryptoBackend( cryptoBackend ) {} const CryptoBackend *cryptoBackend() const { return mCryptoBackend; } enum { RTTI = 0x2EAE3BE0, RTTI_MASK = 0xFFFFFFFF }; int rtti() const { return RTTI; } private: const CryptoBackend *mCryptoBackend; }; // Checklist item under a BackendListViewItem // (e.g. "GpgME supports protocol OpenPGP") class Kleo::ProtocolCheckListItem : public QCheckListItem { public: ProtocolCheckListItem( BackendListViewItem* blvi, QListViewItem* prev, const char * protocolName, const CryptoBackend::Protocol* protocol ) // can be 0 : QCheckListItem( blvi, prev, itemText( protocolName, protocol ), QCheckListItem::CheckBox ), mProtocol( protocol ), mProtocolName( protocolName ) {} enum { RTTI = 0x2EAE3BE1, RTTI_MASK = 0xFFFFFFFF }; virtual int rtti() const { return RTTI; } // can be 0 const CryptoBackend::Protocol* protocol() const { return mProtocol; } const char * protocolName() const { return mProtocolName; } protected: virtual void stateChange( bool b ) { BackendListView* lv = static_cast( listView() ); // "radio-button-like" behavior for the protocol checkboxes if ( b ) lv->deselectAll( mProtocolName, this ); lv->emitChanged(); QCheckListItem::stateChange( b ); } private: // Helper for the constructor. static QString itemText( const char * protocolName, const CryptoBackend::Protocol* protocol ) { // First one is the generic name (find a nice one for OpenPGP, SMIME) const QString protoName = qstricmp( protocolName, "openpgp" ) != 0 ? qstricmp( protocolName, "smime" ) != 0 ? QString::fromLatin1( protocolName ) : i18n( "S/MIME" ) : i18n( "OpenPGP" ); // second one is implementation name (gpg, gpgsm...) const QString impName = protocol ? protocol->displayName() : i18n( "failed" ); return i18n( "Items in Kleo::BackendConfigWidget listview (1: protocol; 2: implementation name)", "%1 (%2)" ).arg( protoName, impName ); } const CryptoBackend::Protocol* mProtocol; // can be 0 const char * mProtocolName; }; const Kleo::CryptoBackend* Kleo::BackendListView::currentBackend() const { const QListViewItem* curItem = currentItem(); if ( !curItem ) // can't happen return 0; if ( lvi_cast( curItem ) ) curItem = curItem->parent(); if ( const Kleo::BackendListViewItem * blvi = lvi_cast( curItem ) ) return blvi->cryptoBackend(); return 0; } // can't be const method due to QListViewItemIterator (why?) const Kleo::CryptoBackend* Kleo::BackendListView::chosenBackend( const char * protocolName ) { for ( QListViewItemIterator it( this /*, QListViewItemIterator::Checked doesn't work*/ ) ; it.current() ; ++it ) if ( ProtocolCheckListItem * p = lvi_cast( it.current() ) ) if ( p->isOn() && qstricmp( p->protocolName(), protocolName ) == 0 ) { // OK that's the one. Now go up to the parent backend // (need to do that in the listview since Protocol doesn't know it) if ( const BackendListViewItem * parItem = lvi_cast( it.current()->parent() ) ) return parItem->cryptoBackend(); } return 0; } void Kleo::BackendListView::deselectAll( const char * protocolName, QCheckListItem* except ) { for ( QListViewItemIterator it( this /*, QListViewItemIterator::Checked doesn't work*/ ) ; it.current() ; ++it ) { if ( it.current() == except ) continue; if ( ProtocolCheckListItem * p = lvi_cast( it.current() ) ) if ( p->isOn() && qstricmp( p->protocolName(), protocolName ) == 0 ) p->setOn( false ); } } //// Kleo::BackendConfigWidget::BackendConfigWidget( CryptoBackendFactory * factory, QWidget * parent, const char * name, WFlags f ) : QWidget( parent, name, f ), d( 0 ) { assert( factory ); d = new Private(); d->backendFactory = factory; QHBoxLayout * hlay = new QHBoxLayout( this, 0, KDialog::spacingHint() ); d->listView = new BackendListView( this, "d->listView" ); d->listView->addColumn( i18n("Available Backends") ); d->listView->setAllColumnsShowFocus( true ); d->listView->setSorting( -1 ); d->listView->header()->setClickEnabled( false ); d->listView->setFullWidth( true ); hlay->addWidget( d->listView, 1 ); connect( d->listView, SIGNAL(selectionChanged(QListViewItem*)), SLOT(slotSelectionChanged(QListViewItem*)) ); QVBoxLayout * vlay = new QVBoxLayout( hlay ); // inherits spacing d->configureButton = new QPushButton( i18n("Confi&gure..."), this ); d->configureButton->setAutoDefault( false ); vlay->addWidget( d->configureButton ); connect( d->configureButton, SIGNAL(clicked()), SLOT(slotConfigureButtonClicked()) ); d->rescanButton = new QPushButton( i18n("Rescan"), this ); d->rescanButton->setAutoDefault( false ); vlay->addWidget( d->rescanButton ); connect( d->rescanButton, SIGNAL(clicked()), SLOT(slotRescanButtonClicked()) ); vlay->addStretch( 1 ); } Kleo::BackendConfigWidget::~BackendConfigWidget() { delete d; d = 0; } void Kleo::BackendConfigWidget::load() { d->listView->clear(); unsigned int backendCount = 0; // populate the plugin list: BackendListViewItem * top = 0; for ( unsigned int i = 0 ; const CryptoBackend * b = d->backendFactory->backend( i ) ; ++i ) { top = new Kleo::BackendListViewItem( d->listView, top, b ); ProtocolCheckListItem * last = 0; for ( int i = 0 ; const char * name = b->enumerateProtocols( i ) ; ++i ) { const CryptoBackend::Protocol * protocol = b->protocol( name ); if ( protocol ) { last = new ProtocolCheckListItem( top, last, name, protocol ); last->setOn( protocol == d->backendFactory->protocol( name ) ); } else if ( b->supportsProtocol( name ) ) { last = new ProtocolCheckListItem( top, last, name, 0 ); last->setOn( false ); last->setEnabled( false ); } } top->setOpen( true ); ++backendCount; } if ( backendCount ) { d->listView->setCurrentItem( d->listView->firstChild() ); d->listView->setSelected( d->listView->firstChild(), true ); } slotSelectionChanged( d->listView->firstChild() ); } void Kleo::BackendConfigWidget::slotSelectionChanged( QListViewItem * ) { const CryptoBackend* backend = d->listView->currentBackend(); if ( backend && !backend->config() ) kdDebug(5150) << "Backend w/o config object!" << endl; d->configureButton->setEnabled( backend && backend->config() ); } void Kleo::BackendConfigWidget::slotRescanButtonClicked() { QStringList reasons; d->backendFactory->scanForBackends( &reasons ); if ( !reasons.empty() ) KMessageBox::informationList( this, i18n("The following problems where encountered during scanning:"), reasons, i18n("Scan Results") ); load(); emit changed( true ); } void Kleo::BackendConfigWidget::slotConfigureButtonClicked() { const CryptoBackend* backend = d->listView->currentBackend(); if ( backend && backend->config() ) { Kleo::CryptoConfigDialog dlg( backend->config(), this ); int result = dlg.exec(); if ( result == QDialog::Accepted ) { // Tell other users of gpgconf (e.g. the s/mime page) that the gpgconf data might have changed kapp->dcopClient()->emitDCOPSignal( "KPIM::CryptoConfig", "changed()", QByteArray() ); // and schedule a rescan, in case the updates make a backend valid QTimer::singleShot( 0, this, SLOT(slotRescanButtonClicked()) ); } } else // shouldn't happen, button is disabled kdWarning(5150) << "Can't configure backend, no config object available" << endl; } void Kleo::BackendConfigWidget::save() const { for ( int i = 0 ; const char * name = d->backendFactory->enumerateProtocols( i ) ; ++i ) d->backendFactory->setProtocolBackend( name, d->listView->chosenBackend( name ) ); } void Kleo::BackendConfigWidget::virtual_hook( int, void* ) {} #include "backendconfigwidget.moc" diff --git a/lib/backends/chiasmus/chiasmuslibrary.h b/lib/ui/backendconfigwidget.h similarity index 56% copy from lib/backends/chiasmus/chiasmuslibrary.h copy to lib/ui/backendconfigwidget.h index 1759b4fc7..0e26655ce 100644 --- a/lib/backends/chiasmus/chiasmuslibrary.h +++ b/lib/ui/backendconfigwidget.h @@ -1,68 +1,76 @@ -/* -*- mode: C++; c-file-style: "gnu" -*- - chiasmuslibrary.h +/* -*- c++ -*- + backendconfigwidget.h This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + Copyright (c) 2002,2004 Klarälvdalens Datakonsult AB + Copyright (c) 2002,2003 Marc Mutz Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. -*/ + */ +#ifndef __KLEO_UI_BACKENDCONFIGWIDGET_H__ +#define __KLEO_UI_BACKENDCONFIGWIDGET_H__ -#ifndef __KLEO_CHIASMUSLIBRARY_H__ -#define __KLEO_CHIASMUSLIBRARY_H__ +#include +#include -#include -#include +namespace Kleo { + class CryptoBackendFactory; +} -class KLibrary; +class QListViewItem; namespace Kleo { - /** - @short small helper class to load xia.o through xia.so and make - the functionality available. - */ - class ChiasmusLibrary { - ChiasmusLibrary(); - ~ChiasmusLibrary(); + class KDE_EXPORT BackendConfigWidget : public QWidget { + Q_OBJECT public: - static const ChiasmusLibrary * instance(); - static void deleteInstance(); + BackendConfigWidget( CryptoBackendFactory * factory, QWidget * parent=0, const char * name=0, WFlags f=0 ); + ~BackendConfigWidget(); - int perform( const QValueVector & args ) const; - private: - typedef int ( *main_func )( int, char** ); - main_func chiasmus( QString * reason=0 ) const; + void load(); + void save() const; + + void emitChanged( bool b ) { emit changed( b ); } + + signals: + void changed( bool ); + + private slots: + void slotSelectionChanged( QListViewItem * ); + void slotRescanButtonClicked(); + void slotConfigureButtonClicked(); private: - static ChiasmusLibrary * self; - mutable KLibrary * mXiaLibrary; + class Private; + Private * d; + protected: + virtual void virtual_hook( int, void* ); }; } - -#endif // __KLEO_CHIASMUSLIBRARY_H__ +#endif // __KLEO_UI_BACKENDCONFIGWIDGET_H__ diff --git a/lib/ui/cryptoconfigdialog.cpp b/lib/ui/cryptoconfigdialog.cpp new file mode 100644 index 000000000..3fa0a97ca --- /dev/null +++ b/lib/ui/cryptoconfigdialog.cpp @@ -0,0 +1,89 @@ +/* + cryptoconfigdialog.h + + This file is part of kgpgcertmanager + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#include "cryptoconfigdialog.h" +#include "cryptoconfigmodule.h" +#include +#include + +Kleo::CryptoConfigDialog::CryptoConfigDialog( Kleo::CryptoConfig* config, QWidget *parent, const char* name ) + : KDialogBase( Swallow, + // Remove the "whats's this" button since we have no support for it + WStyle_Customize | WStyle_DialogBorder | WStyle_Maximize | WStyle_Title | WStyle_SysMenu, + parent, name, true /*modal*/, + i18n( "Configure" ), Default|Cancel|Apply|Ok|User1, + Ok, true /*separator*/, KGuiItem( i18n( "&Reset" ), "undo" ) ) +{ + mMainWidget = new CryptoConfigModule( config, this ); + setMainWidget( mMainWidget ); + connect( mMainWidget, SIGNAL( changed() ), SLOT( slotChanged() ) ); + enableButton( Apply, false ); + + // Automatically assign accelerators + KAcceleratorManager::manage( this ); +} + +void Kleo::CryptoConfigDialog::slotOk() +{ + slotApply(); + accept(); +} + +void Kleo::CryptoConfigDialog::slotCancel() +{ + mMainWidget->cancel(); + reject(); +} + +void Kleo::CryptoConfigDialog::slotDefault() +{ + mMainWidget->defaults(); + slotChanged(); +} + +void Kleo::CryptoConfigDialog::slotApply() +{ + mMainWidget->save(); + enableButton( Apply, false ); +} + +void Kleo::CryptoConfigDialog::slotUser1() // reset +{ + mMainWidget->reset(); + enableButton( Apply, false ); +} + +void Kleo::CryptoConfigDialog::slotChanged() +{ + enableButton( Apply, true ); +} + +#include "cryptoconfigdialog.moc" diff --git a/lib/ui/cryptoconfigmodule.h b/lib/ui/cryptoconfigdialog.h similarity index 59% copy from lib/ui/cryptoconfigmodule.h copy to lib/ui/cryptoconfigdialog.h index df01d5d8a..484c55ea4 100644 --- a/lib/ui/cryptoconfigmodule.h +++ b/lib/ui/cryptoconfigdialog.h @@ -1,68 +1,69 @@ /* - cryptoconfigmodule.h + cryptoconfigdialog.h - This file is part of libkleopatra - Copyright (c) 2004,2005 Klarälvdalens Datakonsult AB + This file is part of kgpgcertmanager + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2, as published by the Free Software Foundation. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#ifndef CRYPTOCONFIGMODULE_H -#define CRYPTOCONFIGMODULE_H +#ifndef CRYPTOCONFIGDIALOG_H +#define CRYPTOCONFIGDIALOG_H -#include - -#include +#include +#include namespace Kleo { class CryptoConfig; - class CryptoConfigComponentGUI; + class CryptoConfigModule; /** - * Crypto Config Module widget, dynamically generated from CryptoConfig - * It's a simple QWidget so that it can be embedded into a dialog or into a KCModule. + * Simple KDialogBase wrapper around CryptoConfigModule */ - class CryptoConfigModule : public KJanusWidget { + class KDE_EXPORT CryptoConfigDialog : public KDialogBase + { Q_OBJECT public: - CryptoConfigModule( Kleo::CryptoConfig* config, QWidget * parent=0, const char * name=0 ); + CryptoConfigDialog( Kleo::CryptoConfig* config, QWidget *parent = 0, const char* name = 0 ); - void save(); - void reset(); // i.e. reload current settings, discarding user input - void defaults(); - void cancel(); + protected: + virtual void slotOk(); + virtual void slotCancel(); + virtual void slotDefault(); + virtual void slotApply(); + virtual void slotUser1(); // reset - signals: - void changed(); + public slots: + void slotChanged(); private: - Kleo::CryptoConfig* mConfig; - QValueList mComponentGUIs; + CryptoConfigModule* mMainWidget; }; } -#endif +#endif /* CRYPTOCONFIGDIALOG_H */ + diff --git a/lib/ui/cryptoconfigmodule.cpp b/lib/ui/cryptoconfigmodule.cpp index c83db918c..6c2128de1 100644 --- a/lib/ui/cryptoconfigmodule.cpp +++ b/lib/ui/cryptoconfigmodule.cpp @@ -1,572 +1,572 @@ /* cryptoconfigmodule.cpp This file is part of kgpgcertmanager Copyright (c) 2004 Klar�vdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2, as published by the Free Software Foundation. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #include "cryptoconfigmodule.h" #include "cryptoconfigmodule_p.h" #include "directoryserviceswidget.h" #include "kdhorizontalline.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace Kleo; inline QPixmap loadIcon( QString s ) { return KGlobal::instance()->iconLoader() ->loadIcon( s.replace( QRegExp( "[^a-zA-Z0-9_]" ), "_" ), KIcon::NoGroup, KIcon::SizeMedium ); } static const KJanusWidget::Face determineJanusFace( const Kleo::CryptoConfig * config ) { return config && config->componentList().size() < 2 ? KJanusWidget::Plain : KJanusWidget::IconList ; } Kleo::CryptoConfigModule::CryptoConfigModule( Kleo::CryptoConfig* config, QWidget * parent, const char * name ) : KJanusWidget( parent, name, determineJanusFace( config ) ), mConfig( config ) { QWidget * vbox = 0; if ( face() == Plain ) { vbox = plainPage(); QVBoxLayout * vlay = new QVBoxLayout( vbox, 0, KDialog::spacingHint() ); vlay->setAutoAdd( true ); } const QStringList components = config->componentList(); for ( QStringList::const_iterator it = components.begin(); it != components.end(); ++it ) { //kdDebug(5150) << "Component " << (*it).local8Bit() << ":" << endl; Kleo::CryptoConfigComponent* comp = config->component( *it ); Q_ASSERT( comp ); if ( comp->groupList().empty() ) continue; if ( face() != Plain ) { vbox = addVBoxPage( comp->description(), QString::null, loadIcon( comp->iconName() ) ); } CryptoConfigComponentGUI* compGUI = new CryptoConfigComponentGUI( this, comp, vbox, (*it).local8Bit() ); // KJanusWidget doesn't seem to have iterators, so we store a copy... mComponentGUIs.append( compGUI ); } } void Kleo::CryptoConfigModule::save() { bool changed = false; QValueList::Iterator it = mComponentGUIs.begin(); for( ; it != mComponentGUIs.end(); ++it ) { if ( (*it)->save() ) changed = true; } if ( changed ) mConfig->sync(true /*runtime*/); } void Kleo::CryptoConfigModule::reset() { QValueList::Iterator it = mComponentGUIs.begin(); for( ; it != mComponentGUIs.end(); ++it ) { (*it)->load(); } } void Kleo::CryptoConfigModule::defaults() { QValueList::Iterator it = mComponentGUIs.begin(); for( ; it != mComponentGUIs.end(); ++it ) { (*it)->defaults(); } } void Kleo::CryptoConfigModule::cancel() { mConfig->clear(); } //// Kleo::CryptoConfigComponentGUI::CryptoConfigComponentGUI( CryptoConfigModule* module, Kleo::CryptoConfigComponent* component, QWidget* parent, const char* name ) : QWidget( parent, name ), mComponent( component ) { QGridLayout * glay = new QGridLayout( this, 1, 3, 0, KDialog::spacingHint() ); const QStringList groups = mComponent->groupList(); if ( groups.size() > 1 ) { glay->setColSpacing( 0, KDHorizontalLine::indentHint() ); for ( QStringList::const_iterator it = groups.begin(), end = groups.end() ; it != end; ++it ) { Kleo::CryptoConfigGroup* group = mComponent->group( *it ); Q_ASSERT( group ); if ( !group ) continue; KDHorizontalLine * hl = new KDHorizontalLine( group->description(), this ); const int row = glay->numRows(); glay->addMultiCellWidget( hl, row, row, 0, 2 ); mGroupGUIs.append( new CryptoConfigGroupGUI( module, group, glay, this ) ); } } else if ( !groups.empty() ) { mGroupGUIs.append( new CryptoConfigGroupGUI( module, mComponent->group( groups.front() ), glay, this ) ); } glay->setRowStretch( glay->numRows(), 1 ); } bool Kleo::CryptoConfigComponentGUI::save() { bool changed = false; QValueList::Iterator it = mGroupGUIs.begin(); for( ; it != mGroupGUIs.end(); ++it ) { if ( (*it)->save() ) changed = true; } return changed; } void Kleo::CryptoConfigComponentGUI::load() { QValueList::Iterator it = mGroupGUIs.begin(); for( ; it != mGroupGUIs.end(); ++it ) (*it)->load(); } void Kleo::CryptoConfigComponentGUI::defaults() { QValueList::Iterator it = mGroupGUIs.begin(); for( ; it != mGroupGUIs.end(); ++it ) (*it)->defaults(); } //// Kleo::CryptoConfigGroupGUI::CryptoConfigGroupGUI( CryptoConfigModule* module, Kleo::CryptoConfigGroup* group, QGridLayout * glay, QWidget* widget, const char* name ) : QObject( module, name ), mGroup( group ) { const int startRow = glay->numRows(); const QStringList entries = mGroup->entryList(); for( QStringList::const_iterator it = entries.begin(), end = entries.end() ; it != end; ++it ) { Kleo::CryptoConfigEntry* entry = group->entry( *it ); Q_ASSERT( entry ); if ( entry->level() > CryptoConfigEntry::Level_Advanced ) continue; CryptoConfigEntryGUI* entryGUI = CryptoConfigEntryGUIFactory::createEntryGUI( module, entry, *it, glay, widget ); if ( entryGUI ) { mEntryGUIs.append( entryGUI ); entryGUI->load(); } } const int endRow = glay->numRows() - 1; if ( endRow < startRow ) return; const QString iconName = group->iconName(); if ( iconName.isEmpty() ) return; QLabel * l = new QLabel( widget ); l->setPixmap( loadIcon( iconName ) ); glay->addMultiCellWidget( l, startRow, endRow, 0, 0, Qt::AlignTop ); } bool Kleo::CryptoConfigGroupGUI::save() { bool changed = false; QValueList::Iterator it = mEntryGUIs.begin(); for( ; it != mEntryGUIs.end(); ++it ) { if ( (*it)->isChanged() ) { (*it)->save(); changed = true; } } return changed; } void Kleo::CryptoConfigGroupGUI::load() { QValueList::Iterator it = mEntryGUIs.begin(); for( ; it != mEntryGUIs.end(); ++it ) (*it)->load(); } void Kleo::CryptoConfigGroupGUI::defaults() { QValueList::Iterator it = mEntryGUIs.begin(); for( ; it != mEntryGUIs.end(); ++it ) (*it)->resetToDefault(); } //// CryptoConfigEntryGUI* Kleo::CryptoConfigEntryGUIFactory::createEntryGUI( CryptoConfigModule* module, Kleo::CryptoConfigEntry* entry, const QString& entryName, QGridLayout * glay, QWidget* widget, const char* name ) { if ( entry->isList() ) { switch( entry->argType() ) { case Kleo::CryptoConfigEntry::ArgType_None: // A list of options with no arguments (e.g. -v -v -v) is shown as a spinbox return new CryptoConfigEntrySpinBox( module, entry, entryName, glay, widget, name ); case Kleo::CryptoConfigEntry::ArgType_Int: case Kleo::CryptoConfigEntry::ArgType_UInt: // Let people type list of numbers (1,2,3....). Untested. return new CryptoConfigEntryLineEdit( module, entry, entryName, glay, widget, name ); case Kleo::CryptoConfigEntry::ArgType_URL: case Kleo::CryptoConfigEntry::ArgType_Path: case Kleo::CryptoConfigEntry::ArgType_DirPath: case Kleo::CryptoConfigEntry::ArgType_String: kdWarning(5150) << "No widget implemented for list of type " << entry->argType() << endl; return 0; // TODO when the need arises :) case Kleo::CryptoConfigEntry::ArgType_LDAPURL: return new CryptoConfigEntryLDAPURL( module, entry, entryName, glay, widget, name ); } kdWarning(5150) << "No widget implemented for list of (unknown) type " << entry->argType() << endl; return 0; } switch( entry->argType() ) { case Kleo::CryptoConfigEntry::ArgType_None: return new CryptoConfigEntryCheckBox( module, entry, entryName, glay, widget, name ); case Kleo::CryptoConfigEntry::ArgType_Int: case Kleo::CryptoConfigEntry::ArgType_UInt: return new CryptoConfigEntrySpinBox( module, entry, entryName, glay, widget, name ); case Kleo::CryptoConfigEntry::ArgType_URL: return new CryptoConfigEntryURL( module, entry, entryName, glay, widget, name ); case Kleo::CryptoConfigEntry::ArgType_Path: return new CryptoConfigEntryPath( module, entry, entryName, glay, widget, name ); case Kleo::CryptoConfigEntry::ArgType_DirPath: return new CryptoConfigEntryDirPath( module, entry, entryName, glay, widget, name ); case Kleo::CryptoConfigEntry::ArgType_LDAPURL: kdWarning(5150) << "No widget implemented for type " << entry->argType() << endl; return 0; // TODO when the need arises :) case Kleo::CryptoConfigEntry::ArgType_String: return new CryptoConfigEntryLineEdit( module, entry, entryName, glay, widget, name ); } kdWarning(5150) << "No widget implemented for (unknown) type " << entry->argType() << endl; return 0; } //// Kleo::CryptoConfigEntryGUI::CryptoConfigEntryGUI( CryptoConfigModule* module, Kleo::CryptoConfigEntry* entry, const QString& entryName, const char* name ) : QObject( module, name ), mEntry( entry ), mName( entryName ), mChanged( false ) { connect( this, SIGNAL( changed() ), module, SIGNAL( changed() ) ); } QString Kleo::CryptoConfigEntryGUI::description() const { QString descr = mEntry->description(); if ( descr.isEmpty() ) // shouldn't happen descr = QString( "<%1>" ).arg( mName ); return descr; } void Kleo::CryptoConfigEntryGUI::resetToDefault() { mEntry->resetToDefault(); load(); } //// Kleo::CryptoConfigEntryLineEdit::CryptoConfigEntryLineEdit( CryptoConfigModule* module, Kleo::CryptoConfigEntry* entry, const QString& entryName, QGridLayout * glay, QWidget* widget, const char* name ) : CryptoConfigEntryGUI( module, entry, entryName, name ) { const int row = glay->numRows(); mLineEdit = new KLineEdit( widget ); glay->addWidget( new QLabel( mLineEdit, description(), widget ), row, 1 ); glay->addWidget( mLineEdit, row, 2 ); connect( mLineEdit, SIGNAL( textChanged( const QString& ) ), SLOT( slotChanged() ) ); } void Kleo::CryptoConfigEntryLineEdit::doSave() { mEntry->setStringValue( mLineEdit->text() ); } void Kleo::CryptoConfigEntryLineEdit::doLoad() { mLineEdit->setText( mEntry->stringValue() ); } //// Kleo::CryptoConfigEntryPath::CryptoConfigEntryPath( CryptoConfigModule* module, Kleo::CryptoConfigEntry* entry, const QString& entryName, QGridLayout * glay, QWidget* widget, const char* name ) : CryptoConfigEntryGUI( module, entry, entryName, name ) { const int row = glay->numRows(); mUrlRequester = new KURLRequester( widget ); mUrlRequester->setMode( KFile::File | KFile::ExistingOnly | KFile::LocalOnly ); glay->addWidget( new QLabel( mUrlRequester, description(), widget ), row, 1 ); glay->addWidget( mUrlRequester, row, 2 ); connect( mUrlRequester, SIGNAL( textChanged( const QString& ) ), SLOT( slotChanged() ) ); } void Kleo::CryptoConfigEntryPath::doSave() { KURL url; url.setPath( mUrlRequester->url() ); mEntry->setURLValue( url ); } void Kleo::CryptoConfigEntryPath::doLoad() { mUrlRequester->setURL( mEntry->urlValue().path() ); } //// Kleo::CryptoConfigEntryDirPath::CryptoConfigEntryDirPath( CryptoConfigModule* module, Kleo::CryptoConfigEntry* entry, const QString& entryName, QGridLayout * glay, QWidget* widget, const char* name ) : CryptoConfigEntryGUI( module, entry, entryName, name ) { const int row = glay->numRows(); mUrlRequester = new KURLRequester( widget ); mUrlRequester->setMode( KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly ); glay->addWidget( new QLabel( mUrlRequester, description(), widget ), row, 1 ); glay->addWidget( mUrlRequester, row, 2 ); connect( mUrlRequester, SIGNAL( textChanged( const QString& ) ), SLOT( slotChanged() ) ); } void Kleo::CryptoConfigEntryDirPath::doSave() { KURL url; url.setPath( mUrlRequester->url() ); mEntry->setURLValue( url ); } void Kleo::CryptoConfigEntryDirPath::doLoad() { mUrlRequester->setURL( mEntry->urlValue().path() ); } //// Kleo::CryptoConfigEntryURL::CryptoConfigEntryURL( CryptoConfigModule* module, Kleo::CryptoConfigEntry* entry, const QString& entryName, QGridLayout * glay, QWidget* widget, const char* name ) : CryptoConfigEntryGUI( module, entry, entryName, name ) { const int row = glay->numRows(); mUrlRequester = new KURLRequester( widget ); mUrlRequester->setMode( KFile::File | KFile::ExistingOnly ); glay->addWidget( new QLabel( mUrlRequester, description(), widget ), row, 1 ); glay->addWidget( mUrlRequester, row, 2 ); connect( mUrlRequester, SIGNAL( textChanged( const QString& ) ), SLOT( slotChanged() ) ); } void Kleo::CryptoConfigEntryURL::doSave() { mEntry->setURLValue( mUrlRequester->url() ); } void Kleo::CryptoConfigEntryURL::doLoad() { mUrlRequester->setURL( mEntry->urlValue().url() ); } //// Kleo::CryptoConfigEntrySpinBox::CryptoConfigEntrySpinBox( CryptoConfigModule* module, Kleo::CryptoConfigEntry* entry, const QString& entryName, QGridLayout * glay, QWidget* widget, const char* name ) : CryptoConfigEntryGUI( module, entry, entryName, name ) { if ( entry->argType() == Kleo::CryptoConfigEntry::ArgType_None && entry->isList() ) { mKind = ListOfNone; } else if ( entry->argType() == Kleo::CryptoConfigEntry::ArgType_UInt ) { mKind = UInt; } else { Q_ASSERT( entry->argType() == Kleo::CryptoConfigEntry::ArgType_Int ); mKind = Int; } const int row = glay->numRows(); mNumInput = new KIntNumInput( widget ); glay->addWidget( new QLabel( mNumInput, description(), widget ), row, 1 ); glay->addWidget( mNumInput, row, 2 ); if ( mKind == UInt || mKind == ListOfNone ) mNumInput->setMinValue( 0 ); connect( mNumInput, SIGNAL( valueChanged(int) ), SLOT( slotChanged() ) ); } void Kleo::CryptoConfigEntrySpinBox::doSave() { int value = mNumInput->value(); switch ( mKind ) { case ListOfNone: mEntry->setNumberOfTimesSet( value ); break; case UInt: mEntry->setUIntValue( value ); break; case Int: mEntry->setIntValue( value ); break; } } void Kleo::CryptoConfigEntrySpinBox::doLoad() { int value = 0; switch ( mKind ) { case ListOfNone: value = mEntry->numberOfTimesSet(); break; case UInt: value = mEntry->uintValue(); break; case Int: value = mEntry->intValue(); break; } mNumInput->setValue( value ); } //// Kleo::CryptoConfigEntryCheckBox::CryptoConfigEntryCheckBox( CryptoConfigModule* module, Kleo::CryptoConfigEntry* entry, const QString& entryName, QGridLayout * glay, QWidget* widget, const char* name ) : CryptoConfigEntryGUI( module, entry, entryName, name ) { const int row = glay->numRows(); mCheckBox = new QCheckBox( widget ); glay->addMultiCellWidget( mCheckBox, row, row, 1, 2 ); mCheckBox->setText( description() ); connect( mCheckBox, SIGNAL( toggled(bool) ), SLOT( slotChanged() ) ); } void Kleo::CryptoConfigEntryCheckBox::doSave() { mEntry->setBoolValue( mCheckBox->isChecked() ); } void Kleo::CryptoConfigEntryCheckBox::doLoad() { mCheckBox->setChecked( mEntry->boolValue() ); } Kleo::CryptoConfigEntryLDAPURL::CryptoConfigEntryLDAPURL( CryptoConfigModule* module, Kleo::CryptoConfigEntry* entry, const QString& entryName, QGridLayout * glay, QWidget* widget, const char* name ) : CryptoConfigEntryGUI( module, entry, entryName, name ) { mLabel = new QLabel( widget ); mPushButton = new QPushButton( i18n( "Edit..." ), widget ); const int row = glay->numRows(); glay->addWidget( new QLabel( mPushButton, description(), widget ), row, 1 ); QHBoxLayout * hlay = new QHBoxLayout; glay->addLayout( hlay, row, 2 ); hlay->addWidget( mLabel, 1 ); hlay->addWidget( mPushButton ); connect( mPushButton, SIGNAL( clicked() ), SLOT( slotOpenDialog() ) ); } void Kleo::CryptoConfigEntryLDAPURL::doLoad() { setURLList( mEntry->urlValueList() ); } void Kleo::CryptoConfigEntryLDAPURL::doSave() { mEntry->setURLValueList( mURLList ); } void Kleo::CryptoConfigEntryLDAPURL::slotOpenDialog() { // I'm a bad boy and I do it all on the stack. Enough classes already :) // This is just a simple dialog around the directory-services-widget KDialogBase dialog( mPushButton->parentWidget(), 0, true /*modal*/, i18n( "Configure LDAP Servers" ), KDialogBase::Default|KDialogBase::Cancel|KDialogBase::Ok, KDialogBase::Ok, true /*separator*/ ); DirectoryServicesWidget* dirserv = new DirectoryServicesWidget( mEntry, &dialog ); dirserv->load(); dialog.setMainWidget( dirserv ); connect( &dialog, SIGNAL( defaultClicked() ), dirserv, SLOT( defaults() ) ); if ( dialog.exec() ) { // Note that we just grab the urls from the dialog, we don't call its save method, // since the user hasn't confirmed the big config dialog yet. setURLList( dirserv->urlList() ); slotChanged(); } } void Kleo::CryptoConfigEntryLDAPURL::setURLList( const KURL::List& urlList ) { mURLList = urlList; if ( mURLList.isEmpty() ) mLabel->setText( i18n( "No server configured yet" ) ); else mLabel->setText( i18n( "1 server configured", "%n servers configured", mURLList.count() ) ); } #include "cryptoconfigmodule.moc" #include "cryptoconfigmodule_p.moc" diff --git a/lib/ui/cryptoconfigmodule.h b/lib/ui/cryptoconfigmodule.h index df01d5d8a..185814594 100644 --- a/lib/ui/cryptoconfigmodule.h +++ b/lib/ui/cryptoconfigmodule.h @@ -1,68 +1,68 @@ /* cryptoconfigmodule.h This file is part of libkleopatra Copyright (c) 2004,2005 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2, as published by the Free Software Foundation. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifndef CRYPTOCONFIGMODULE_H #define CRYPTOCONFIGMODULE_H #include #include namespace Kleo { class CryptoConfig; class CryptoConfigComponentGUI; /** * Crypto Config Module widget, dynamically generated from CryptoConfig * It's a simple QWidget so that it can be embedded into a dialog or into a KCModule. */ class CryptoConfigModule : public KJanusWidget { Q_OBJECT public: CryptoConfigModule( Kleo::CryptoConfig* config, QWidget * parent=0, const char * name=0 ); void save(); void reset(); // i.e. reload current settings, discarding user input void defaults(); void cancel(); signals: void changed(); private: Kleo::CryptoConfig* mConfig; QValueList mComponentGUIs; }; } #endif diff --git a/lib/ui/cryptoconfigmodule_p.h b/lib/ui/cryptoconfigmodule_p.h index 4a3d6e5db..22145f323 100644 --- a/lib/ui/cryptoconfigmodule_p.h +++ b/lib/ui/cryptoconfigmodule_p.h @@ -1,280 +1,280 @@ /* cryptoconfigmodule_p.h This file is part of libkleopatra Copyright (c) 2004,2005 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2, as published by the Free Software Foundation. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifndef CRYPTOCONFIGMODULE_P_H #define CRYPTOCONFIGMODULE_P_H #include #include #include #include class KLineEdit; class KIntNumInput; class KURLRequester; class QPushButton; class QGridLayout; namespace Kleo { class CryptoConfig; class CryptoConfigComponent; class CryptoConfigGroup; class CryptoConfigEntry; class CryptoConfigComponentGUI; class CryptoConfigGroupGUI; class CryptoConfigEntryGUI; /** * A widget corresponding to a component in the crypto config */ class CryptoConfigComponentGUI : public QWidget { Q_OBJECT public: CryptoConfigComponentGUI( CryptoConfigModule* module, Kleo::CryptoConfigComponent* component, QWidget* parent, const char* name = 0 ); bool save(); void load(); void defaults(); private: Kleo::CryptoConfigComponent* mComponent; QValueList mGroupGUIs; }; /** * A class managing widgets corresponding to a group in the crypto config */ class CryptoConfigGroupGUI : public QObject { Q_OBJECT public: CryptoConfigGroupGUI( CryptoConfigModule* module, Kleo::CryptoConfigGroup* group, QGridLayout * layout, QWidget* parent, const char* name = 0 ); bool save(); void load(); void defaults(); private: Kleo::CryptoConfigGroup* mGroup; QValueList mEntryGUIs; }; /** * Factory for CryptoConfigEntryGUI instances * Not a real factory, but can become one later. */ class CryptoConfigEntryGUIFactory { public: static CryptoConfigEntryGUI* createEntryGUI( CryptoConfigModule* module, Kleo::CryptoConfigEntry* entry, const QString& entryName, QGridLayout * layout, QWidget* widget, const char* name = 0 ); }; /** * Base class for the widget managers tied to an entry in the crypto config */ class CryptoConfigEntryGUI : public QObject { Q_OBJECT public: CryptoConfigEntryGUI( CryptoConfigModule* module, Kleo::CryptoConfigEntry* entry, const QString& entryName, const char* name = 0 ); virtual ~CryptoConfigEntryGUI() {} void load() { doLoad(); mChanged = false; } void save() { Q_ASSERT( mChanged ); doSave(); mChanged = false; } void resetToDefault(); QString description() const; bool isChanged() const { return mChanged; } signals: void changed(); protected slots: void slotChanged() { mChanged = true; emit changed(); } protected: virtual void doSave() = 0; virtual void doLoad() = 0; Kleo::CryptoConfigEntry* mEntry; QString mName; bool mChanged; }; /** * A widget manager for a string entry in the crypto config */ class CryptoConfigEntryLineEdit : public CryptoConfigEntryGUI { Q_OBJECT public: CryptoConfigEntryLineEdit( CryptoConfigModule* module, Kleo::CryptoConfigEntry* entry, const QString& entryName, QGridLayout * layout, QWidget* parent, const char* name = 0 ); virtual void doSave(); virtual void doLoad(); private: KLineEdit* mLineEdit; }; /** * A widget manager for a path entry in the crypto config */ class CryptoConfigEntryPath : public CryptoConfigEntryGUI { Q_OBJECT public: CryptoConfigEntryPath( CryptoConfigModule* module, Kleo::CryptoConfigEntry* entry, const QString& entryName, QGridLayout * layout, QWidget* parent, const char* name = 0 ); virtual void doSave(); virtual void doLoad(); private: KURLRequester* mUrlRequester; }; /** * A widget manager for a directory path entry in the crypto config */ class CryptoConfigEntryDirPath : public CryptoConfigEntryGUI { Q_OBJECT public: CryptoConfigEntryDirPath( CryptoConfigModule* module, Kleo::CryptoConfigEntry* entry, const QString& entryName, QGridLayout * layout, QWidget* parent, const char* name = 0 ); virtual void doSave(); virtual void doLoad(); private: KURLRequester* mUrlRequester; }; /** * A widget manager for an URL entry in the crypto config */ class CryptoConfigEntryURL : public CryptoConfigEntryGUI { Q_OBJECT public: CryptoConfigEntryURL( CryptoConfigModule* module, Kleo::CryptoConfigEntry* entry, const QString& entryName, QGridLayout * layout, QWidget* parent, const char* name = 0 ); virtual void doSave(); virtual void doLoad(); private: KURLRequester * mUrlRequester; }; /** * A widget manager for an int/uint entry in the crypto config */ class CryptoConfigEntrySpinBox : public CryptoConfigEntryGUI { Q_OBJECT public: CryptoConfigEntrySpinBox( CryptoConfigModule* module, Kleo::CryptoConfigEntry* entry, const QString& entryName, QGridLayout * layout, QWidget* parent, const char* name = 0 ); virtual void doSave(); virtual void doLoad(); private: enum { Int, UInt, ListOfNone } mKind; KIntNumInput* mNumInput; }; /** * A widget manager for a bool entry in the crypto config */ class CryptoConfigEntryCheckBox : public CryptoConfigEntryGUI { Q_OBJECT public: CryptoConfigEntryCheckBox( CryptoConfigModule* module, Kleo::CryptoConfigEntry* entry, const QString& entryName, QGridLayout * layout, QWidget* parent, const char* name = 0 ); virtual void doSave(); virtual void doLoad(); private: QCheckBox* mCheckBox; }; /** * A widget manager for a bool entry in the crypto config */ class CryptoConfigEntryLDAPURL : public CryptoConfigEntryGUI { Q_OBJECT public: CryptoConfigEntryLDAPURL( CryptoConfigModule* module, Kleo::CryptoConfigEntry* entry, const QString& entryName, QGridLayout * layout, QWidget* parent, const char* name = 0 ); virtual void doSave(); virtual void doLoad(); private slots: void slotOpenDialog(); private: void setURLList( const KURL::List& urlList ); QLabel* mLabel; QPushButton* mPushButton; KURL::List mURLList; }; } #endif // CRYPTOCONFIGMODULE_P_H diff --git a/lib/ui/directoryserviceswidget.cpp b/lib/ui/directoryserviceswidget.cpp new file mode 100644 index 000000000..76c1b3dda --- /dev/null +++ b/lib/ui/directoryserviceswidget.cpp @@ -0,0 +1,308 @@ +/* + directoryserviceswidget.cpp + + This file is part of Kleopatra, the KDE keymanager + Copyright (c) 2001,2002,2004 Klar�vdalens Datakonsult AB + + Kleopatra is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + Kleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#include + +#include "directoryserviceswidget.h" +#include "adddirectoryservicedialogimpl.h" +#include "cryptplugwrapper.h" + +#include +#include +#include +#include + +#include +#include +#include +#include + +using namespace Kleo; + +class QX500ListViewItem : public QListViewItem +{ +public: + QX500ListViewItem( QListView* lv, QListViewItem* prev, + const QString& serverName, + const QString& portNumber, + const QString& dn, + const QString& username, + const QString& password ) + : QListViewItem( lv, prev, serverName, portNumber, dn, username ) { + setPassword( password ); + } + + void setPassword( const QString& pass ) { + mPassword = pass; + setText( 4, pass.isEmpty() ? QString::null : QString::fromLatin1( "******" ) ); + } + + const QString& password() const { return mPassword; } + + void setData( const QString& serverName, + const QString& portNumber, + const QString& dn, + const QString& username, + const QString& password ) { + setText( 0, serverName ); + setText( 1, portNumber ); + setText( 2, dn ); + setText( 3, username ); + setPassword( password ); + } + + void copyItem( QX500ListViewItem* item ) { + for ( unsigned int i = 0; i < 4 ; ++i ) + setText( i, item->text( i ) ); + setPassword( item->password() ); + } + +private: + QString mPassword; +}; + +Kleo::DirectoryServicesWidget::DirectoryServicesWidget( + Kleo::CryptoConfigEntry* configEntry, + QWidget* parent, const char* name, WFlags fl ) + : DirectoryServicesWidgetBase( parent, name, fl ), + mConfigEntry( configEntry ) +{ + x500LV->setSorting( -1 ); + + // taken from kmail's configuredialog.cpp + upButton->setIconSet( BarIconSet( "up", KIcon::SizeSmall ) ); + upButton->setEnabled( false ); // b/c no item is selected yet + + downButton->setIconSet( BarIconSet( "down", KIcon::SizeSmall ) ); + downButton->setEnabled( false ); // b/c no item is selected yet +} + + +/* + * Destroys the object and frees any allocated resources + */ +DirectoryServicesWidget::~DirectoryServicesWidget() +{ + // no need to delete child widgets, Qt does it all for us +} + + +/** + Enables or disables the widgets in this dialog according to the + capabilities of the current plugin passed as a parameter. +*/ +void DirectoryServicesWidget::enableDisable( CryptPlugWrapper* cryptPlug ) // unused? +{ + // disable the whole page if the plugin does not support the use + // of directory services + setEnabled( cryptPlug->hasFeature( Feature_CertificateDirectoryService ) || + cryptPlug->hasFeature( Feature_CRLDirectoryService ) ); +} + + +/* + * protected slot, connected to selectionChanged() + */ +void DirectoryServicesWidget::slotServiceChanged( QListViewItem* item ) +{ + if( item ) + removeServicePB->setEnabled( true ); + else + removeServicePB->setEnabled( false ); + downButton->setEnabled( item && item->itemBelow() ); + upButton->setEnabled( item && item->itemAbove() ); +} + + +/* + * protected slot, connected to returnPressed/doubleClicked + */ +void DirectoryServicesWidget::slotServiceSelected( QListViewItem* item ) +{ + AddDirectoryServiceDialogImpl* dlg = new AddDirectoryServiceDialogImpl( this ); + dlg->serverNameED->setText( item->text( 0 ) ); + dlg->portED->setText( item->text( 1 ) ); + dlg->descriptionED->setText( item->text( 2 ) ); + dlg->usernameED->setText( item->text( 3 ) ); + QString pass = static_cast( item )->password(); + dlg->passwordED->setText( pass ); + + if( dlg->exec() == QDialog::Accepted ) { + item->setText( 0, dlg->serverNameED->text() ); + item->setText( 1, dlg->portED->text() ); + item->setText( 2, dlg->descriptionED->text() ); + item->setText( 3, dlg->usernameED->text() ); + static_cast( item )->setPassword( dlg->passwordED->text() ); + emit changed(); + } + delete dlg; +} + + +/* + * protected slot + */ +void DirectoryServicesWidget::slotAddService() +{ + AddDirectoryServiceDialogImpl* dlg = new AddDirectoryServiceDialogImpl( this ); + if( dlg->exec() == QDialog::Accepted ) { + QX500ListViewItem *item = new QX500ListViewItem( x500LV, x500LV->lastItem(), + dlg->serverNameED->text(), + dlg->portED->text(), + dlg->descriptionED->text(), + dlg->usernameED->text(), + dlg->passwordED->text() ); + slotServiceChanged(item); + emit changed(); + } + delete dlg; +} + +/* + * protected slot + */ +void DirectoryServicesWidget::slotDeleteService() +{ + QListViewItem* item = x500LV->selectedItem(); + Q_ASSERT( item ); + if( !item ) + return; + else + delete item; + x500LV->triggerUpdate(); + item = x500LV->currentItem(); + x500LV->setCurrentItem( item ); // seems necessary... + x500LV->setSelected( item, true ); + emit changed(); +} + + +void DirectoryServicesWidget::setInitialServices( const KURL::List& urls ) +{ + x500LV->clear(); + for( KURL::List::const_iterator it = urls.begin(); it != urls.end(); ++it ) { + QString dn = KURL::decode_string( (*it).query().mid( 1 ) ); // decode query and skip leading '?' + (void)new QX500ListViewItem( x500LV, x500LV->lastItem(), + (*it).host(), + QString::number( (*it).port() ), + dn, + (*it).user(), + (*it).pass()); + } +} + +KURL::List DirectoryServicesWidget::urlList() const +{ + KURL::List lst; + QListViewItemIterator it( x500LV ); + for ( ; it.current() ; ++it ) { + QListViewItem* item = it.current(); + KURL url; + url.setProtocol( "ldap" ); + url.setHost( item->text( 0 ) ); + url.setPort( item->text( 1 ).toInt() ); + url.setPath( "/" ); // workaround KURL parsing bug + url.setQuery( item->text( 2 ) ); + url.setUser( item->text( 3 ) ); + url.setPass( static_cast( item )->password() ); + kdDebug() << url << endl; + lst << url; + } + return lst; +} + +void DirectoryServicesWidget::clear() +{ + x500LV->clear(); + emit changed(); +} + +void DirectoryServicesWidget::load() +{ + if ( mConfigEntry ) { + setInitialServices( mConfigEntry->urlValueList() ); + } +} + +void DirectoryServicesWidget::save() +{ + if ( mConfigEntry ) { + mConfigEntry->setURLValueList( urlList() ); + } +} + +void DirectoryServicesWidget::defaults() +{ + if ( mConfigEntry ) { + // resetToDefault doesn't work since gpgconf doesn't know any defaults for this entry. + //mConfigEntry->resetToDefault(); + //load(); + clear(); // the default is an empty list. + } +} + +static void swapItems( QX500ListViewItem *item, QX500ListViewItem *other ) +{ + QString serverName = item->text( 0 ); + QString portNumber = item->text( 1 ); + QString dn = item->text( 2 ); + QString username = item->text( 3 ); + QString password = item->password(); + item->copyItem( other ); + other->setData( serverName, portNumber, dn, username, password ); +} + +void Kleo::DirectoryServicesWidget::slotMoveUp() +{ + QX500ListViewItem *item = static_cast( x500LV->selectedItem() ); + if ( !item ) return; + QX500ListViewItem *above = static_cast( item->itemAbove() ); + if ( !above ) return; + swapItems( item, above ); + x500LV->setCurrentItem( above ); + x500LV->setSelected( above, true ); + emit changed(); +} + +void Kleo::DirectoryServicesWidget::slotMoveDown() +{ + QX500ListViewItem *item = static_cast( x500LV->selectedItem() ); + if ( !item ) return; + QX500ListViewItem *below = static_cast( item->itemBelow() ); + if ( !below ) return; + swapItems( item, below ); + x500LV->setCurrentItem( below ); + x500LV->setSelected( below, true ); + emit changed(); +} + +#include "directoryserviceswidget.moc" diff --git a/kwatchgnupg/aboutdata.cpp b/lib/ui/directoryserviceswidget.h similarity index 52% copy from kwatchgnupg/aboutdata.cpp copy to lib/ui/directoryserviceswidget.h index 68c918e9d..02e428c95 100644 --- a/kwatchgnupg/aboutdata.cpp +++ b/lib/ui/directoryserviceswidget.h @@ -1,73 +1,82 @@ /* - aboutdata.cpp + directoryserviceswidget.h This file is part of Kleopatra, the KDE keymanager - Copyright (c) 2004 Klar�vdalens Datakonsult AB + Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB Kleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Kleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -#include "aboutdata.h" +#ifndef DIRECTORYSERVICESWIDGET_H +#define DIRECTORYSERVICESWIDGET_H +#include "directoryserviceswidgetbase.h" +#include +#include -#include +class CryptPlugWrapper; +namespace Kleo { -static const char kwatchgnupg_version[] = "1.0"; -static const char description[] = I18N_NOOP("GnuPG log viewer"); +class CryptoConfigEntry; -struct about_data { - const char * name; - const char * desc; - const char * email; - const char * web; -}; +class KDE_EXPORT DirectoryServicesWidget : public DirectoryServicesWidgetBase +{ + Q_OBJECT -static const about_data authors[] = { - { "Steffen Hansen", I18N_NOOP("Original Author"), "hansen@kde.org", 0 }, -}; +public: + DirectoryServicesWidget( + Kleo::CryptoConfigEntry* configEntry, + QWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); + ~DirectoryServicesWidget(); + + void load(); + void save(); + + void enableDisable( CryptPlugWrapper* wrapper ); // unused? + void setInitialServices( const KURL::List& urls ); + KURL::List urlList() const; + void clear(); -#if 0 -// can't create zero size array - doesn't compile -static const about_data credits[] = { - // PENDING(steffen) add stuff +public slots: + void defaults(); + +signals: + void changed(); + +protected slots: + void slotServiceChanged( QListViewItem* ); + void slotServiceSelected( QListViewItem* ); + void slotAddService(); + void slotDeleteService(); + void slotMoveUp(); + void slotMoveDown(); + +private: + Kleo::CryptoConfigEntry* mConfigEntry; }; -#endif -AboutData::AboutData() - : KAboutData( "kwatchgnupg", I18N_NOOP("KWatchGnuPG"), - kwatchgnupg_version, description, License_GPL, - "(c) 2004 Klar\xC3\xA4lvdalens Datakonsult AB\n" ) -{ - using ::authors; - //using ::credits; - for ( unsigned int i = 0 ; i < sizeof authors / sizeof *authors ; ++i ) - addAuthor( authors[i].name, authors[i].desc, - authors[i].email, authors[i].web ); -#if 0 - for ( unsigned int i = 0 ; i < sizeof credits / sizeof *credits ; ++i ) - addCredit( credits[i].name, credits[i].desc, - credits[i].email, credits[i].web ); -#endif } + +#endif // DIRECTORYSERVICESWIDGET_H diff --git a/lib/ui/dnattributeorderconfigwidget.cpp b/lib/ui/dnattributeorderconfigwidget.cpp new file mode 100644 index 000000000..ad2ec69fe --- /dev/null +++ b/lib/ui/dnattributeorderconfigwidget.cpp @@ -0,0 +1,309 @@ +/* -*- c++ -*- + dnattributeorderconfigwidget.cpp + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klar�vdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "dnattributeorderconfigwidget.h" + +#include "kleo/dn.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +struct Kleo::DNAttributeOrderConfigWidget::Private { + enum { UUp=0, Up=1, Left=2, Right=3, Down=4, DDown=5 }; + + QListView * availableLV; + QListView * currentLV; + QToolButton * navTB[6]; + + QListViewItem * placeHolderItem; + + Kleo::DNAttributeMapper * mapper; +}; + +static void prepare( QListView * lv ) { + lv->setAllColumnsShowFocus( true ); + lv->setResizeMode( QListView::LastColumn ); + lv->header()->setClickEnabled( false ); + lv->addColumn( QString::null ); + lv->addColumn( i18n("Description") ); +} + +Kleo::DNAttributeOrderConfigWidget::DNAttributeOrderConfigWidget( DNAttributeMapper * mapper, QWidget * parent, const char * name, WFlags f ) + : QWidget( parent, name, f ), d( 0 ) +{ + assert( mapper ); + d = new Private(); + d->mapper = mapper; + + QGridLayout * glay = new QGridLayout( this, 2, 3, 0, KDialog::spacingHint() ); + glay->setColStretch( 0, 1 ); + glay->setColStretch( 2, 1 ); + + int row = -1; + + ++row; + glay->addWidget( new QLabel( i18n("Available attributes:"), this ), row, 0 ); + glay->addWidget( new QLabel( i18n("Current attribute order:"), this ), row, 2 ); + + + ++row; + glay->setRowStretch( row, 1 ); + + d->availableLV = new QListView( this ); + prepare( d->availableLV ); + d->availableLV->setSorting( 0 ); + glay->addWidget( d->availableLV, row, 0 ); + + d->currentLV = new QListView( this ); + prepare( d->currentLV ); + d->currentLV->setSorting( -1 ); + glay->addWidget( d->currentLV, row, 2 ); + + connect( d->availableLV, SIGNAL(selectionChanged(QListViewItem*)), + SLOT(slotAvailableSelectionChanged(QListViewItem*)) ); + connect( d->currentLV, SIGNAL(selectionChanged(QListViewItem*)), + SLOT(slotCurrentOrderSelectionChanged(QListViewItem*)) ); + + d->placeHolderItem = new QListViewItem( d->availableLV, "_X_", i18n("All others") ); + + // the up/down/left/right arrow cross: + + QGridLayout * xlay = new QGridLayout( 5, 3, 0, "xlay" ); + xlay->setAlignment( AlignCenter ); + + static const struct { + const char * icon; + int row, col; + const char * tooltip; + const char * slot; + } navButtons[] = { + { "2uparrow", 0, 1, I18N_NOOP( "Move to top" ), SLOT(slotDoubleUpButtonClicked()) }, + { "1uparrow", 1, 1, I18N_NOOP( "Move one up" ), SLOT(slotUpButtonClicked()) }, + { "1leftarrow", 2, 0, I18N_NOOP( "Remove from current attribute order" ), SLOT(slotLeftButtonClicked()) }, + { "1rightarrow", 2, 2, I18N_NOOP( "Add to current attribute order" ), SLOT(slotRightButtonClicked()) }, + { "1downarrow", 3, 1, I18N_NOOP( "Move one down" ), SLOT(slotDownButtonClicked()) }, + { "2downarrow", 4, 1, I18N_NOOP( "Move to bottom" ), SLOT(slotDoubleDownButtonClicked()) } + }; + + for ( unsigned int i = 0 ; i < sizeof navButtons / sizeof *navButtons ; ++i ) { + QToolButton * tb = d->navTB[i] = new QToolButton( this ); + tb->setIconSet( SmallIconSet( navButtons[i].icon ) ); + tb->setEnabled( false ); + QToolTip::add( tb, i18n( navButtons[i].tooltip ) ); + xlay->addWidget( tb, navButtons[i].row, navButtons[i].col ); + connect( tb, SIGNAL(clicked()), navButtons[i].slot ); + } + + glay->addLayout( xlay, row, 1 ); +} + +Kleo::DNAttributeOrderConfigWidget::~DNAttributeOrderConfigWidget() { + delete d; d = 0; +} + +void Kleo::DNAttributeOrderConfigWidget::load() { + // save the _X_ item: + takePlaceHolderItem(); + // clear the rest: + d->availableLV->clear(); + d->currentLV->clear(); + + const QStringList order = d->mapper->attributeOrder(); + + // fill the RHS listview: + QListViewItem * last = 0; + for ( QStringList::const_iterator it = order.begin() ; it != order.end() ; ++it ) { + const QString attr = (*it).upper(); + if ( attr == "_X_" ) { + takePlaceHolderItem(); + d->currentLV->insertItem( d->placeHolderItem ); + d->placeHolderItem->moveItem( last ); + last = d->placeHolderItem; + } else + last = new QListViewItem( d->currentLV, last, attr, d->mapper->name2label( attr ) ); + } + + // fill the LHS listview with what's left: + + const QStringList all = Kleo::DNAttributeMapper::instance()->names(); + for ( QStringList::const_iterator it = all.begin() ; it != all.end() ; ++it ) + if ( order.find( *it ) == order.end() ) + (void)new QListViewItem( d->availableLV, *it, d->mapper->name2label( *it ) ); + + if ( !d->placeHolderItem->listView() ) + d->availableLV->insertItem( d->placeHolderItem ); +} + +void Kleo::DNAttributeOrderConfigWidget::takePlaceHolderItem() { + if ( QListView * lv = d->placeHolderItem->listView() ) + lv->takeItem( d->placeHolderItem ); +} + +void Kleo::DNAttributeOrderConfigWidget::save() const { + QStringList order; + for ( QListViewItemIterator it( d->currentLV ) ; it.current() ; ++it ) + order.push_back( it.current()->text( 0 ) ); + + d->mapper->setAttributeOrder( order ); +} + +void Kleo::DNAttributeOrderConfigWidget::defaults() { + kdDebug() << "Sorry, not implemented: Kleo::DNAttributeOrderConfigWidget::defaults()" << endl; +} + + + +void Kleo::DNAttributeOrderConfigWidget::slotAvailableSelectionChanged( QListViewItem * item ) { + d->navTB[Private::Right]->setEnabled( item ); +} + +void Kleo::DNAttributeOrderConfigWidget::slotCurrentOrderSelectionChanged( QListViewItem * item ) { + enableDisableButtons( item ); +} + +void Kleo::DNAttributeOrderConfigWidget::enableDisableButtons( QListViewItem * item ) { + d->navTB[Private::UUp ]->setEnabled( item && item->itemAbove() ); + d->navTB[Private::Up ]->setEnabled( item && item->itemAbove() ); + d->navTB[Private::Left ]->setEnabled( item ); + d->navTB[Private::Down ]->setEnabled( item && item->itemBelow() ); + d->navTB[Private::DDown]->setEnabled( item && item->itemBelow() ); +} + +void Kleo::DNAttributeOrderConfigWidget::slotUpButtonClicked() { + QListViewItem * item = d->currentLV->selectedItem(); + if ( !item ) + return; + QListViewItem * above = item->itemAbove(); + if ( !above ) + return; + above->moveItem( item ); // moves "above" to after "item", ie. "item" one up + enableDisableButtons( item ); + emit changed(); +} + +void Kleo::DNAttributeOrderConfigWidget::slotDoubleUpButtonClicked() { + QListViewItem * item = d->currentLV->selectedItem(); + if ( !item ) + return; + if ( item == d->currentLV->firstChild() ) + return; + d->currentLV->takeItem( item ); + d->currentLV->insertItem( item ); + d->currentLV->setSelected( item, true ); + enableDisableButtons( item ); + emit changed(); +} + +void Kleo::DNAttributeOrderConfigWidget::slotDownButtonClicked() { + QListViewItem * item = d->currentLV->selectedItem(); + if ( !item ) + return; + QListViewItem * below = item->itemBelow(); + if ( !below ) + return; + item->moveItem( below ); // moves "item" to after "below", ie. "item" one down + enableDisableButtons( item ); + emit changed(); +} + +void Kleo::DNAttributeOrderConfigWidget::slotDoubleDownButtonClicked() { + QListViewItem * item = d->currentLV->selectedItem(); + if ( !item ) + return; + QListViewItem * last = d->currentLV->lastItem(); + assert( last ); + if ( item == last ) + return; + item->moveItem( last ); // moves "item" to after "last", ie. to the bottom + enableDisableButtons( item ); + emit changed(); +} + +void Kleo::DNAttributeOrderConfigWidget::slotLeftButtonClicked() { + QListViewItem * right = d->currentLV->selectedItem(); + if ( !right ) + return; + QListViewItem * next = right->itemBelow(); + if ( !next ) + next = right->itemAbove(); + d->currentLV->takeItem( right ); + d->availableLV->insertItem( right ); + if ( next ) + d->currentLV->setSelected( next, true ); + enableDisableButtons( next ); + emit changed(); +} + +void Kleo::DNAttributeOrderConfigWidget::slotRightButtonClicked() { + QListViewItem * left = d->availableLV->selectedItem(); + if ( !left ) + return; + QListViewItem * next = left->itemBelow(); + if ( !next ) + next = left->itemAbove(); + d->availableLV->takeItem( left ); + d->currentLV->insertItem( left ); + if ( QListViewItem * right = d->currentLV->selectedItem() ) { + if ( QListViewItem * above = right->itemAbove() ) + left->moveItem( above ); // move new item immediately before old selected + d->currentLV->setSelected( right, false ); + } + d->currentLV->setSelected( left, true ); + enableDisableButtons( left ); + d->navTB[Private::Right]->setEnabled( next ); + if ( next ) + d->availableLV->setSelected( next, true ); + emit changed(); +} + + + +void Kleo::DNAttributeOrderConfigWidget::virtual_hook( int, void* ) {} + +#include "dnattributeorderconfigwidget.moc" diff --git a/lib/kleo/specialjob.h b/lib/ui/dnattributeorderconfigwidget.h similarity index 50% copy from lib/kleo/specialjob.h copy to lib/ui/dnattributeorderconfigwidget.h index 106257428..11299ab37 100644 --- a/lib/kleo/specialjob.h +++ b/lib/ui/dnattributeorderconfigwidget.h @@ -1,86 +1,87 @@ -/* - specialjob.h +/* -*- c++ -*- + dnattributeorderconfigwidget.h This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. -*/ + */ -#ifndef __KLEO_SPECIALJOB_H__ -#define __KLEO_SPECIALJOB_H__ - -#include "job.h" - -namespace GpgME { - class Error; -} +#ifndef __KLEO_UI_DNATTRIBUTEORDERCONFIGWIDGET_H__ +#define __KLEO_UI_DNATTRIBUTEORDERCONFIGWIDGET_H__ +#include +#include namespace Kleo { + class DNAttributeMapper; +} - /** - @short An abstract base class for protocol-specific jobs - - To use a SpecialJob, first obtain an instance from the - CryptoBackend implementation, connect progress() and result() - signals to suitable slots and then start the job with a call to - start(). This call might fail, in which case the SpecialJob - instance will have schedules its own destruction with a call to - QObject::deleteLater(). - - After result() is emitted, the SpecialJob will schedule its own - destruction by calling QObject::deleteLater(). +class QListViewItem; - Parameters are set using the Qt property system. More general, or - constructor parameters are given in the call to - Kleo::CryptoBackend::Protocol::specialJob(). +namespace Kleo { - The result is made available through the result signal, and - through the read-only result property, the latter of which needs - to be defined in each SpecialJob subclass. - */ - class SpecialJob : public Job { + class KDE_EXPORT DNAttributeOrderConfigWidget : public QWidget { Q_OBJECT - protected: - SpecialJob( QObject * parent, const char * name ); - public: - ~SpecialJob(); + /*! Use Kleo::DNAttributeMapper::instance()->configWidget( parent, name ) instead. */ + DNAttributeOrderConfigWidget( DNAttributeMapper * mapper, QWidget * parent=0, const char * name=0, WFlags f=0 ); + ~DNAttributeOrderConfigWidget(); - /** - Starts the special operation. - */ - virtual GpgME::Error start() = 0; - - virtual GpgME::Error exec() = 0; + void load(); + void save() const; + void defaults(); signals: - void result( const GpgME::Error & result, const QVariant & data ); + void changed(); + + // + // only boring stuff below... + // + + private slots: + void slotAvailableSelectionChanged( QListViewItem * ); + void slotCurrentOrderSelectionChanged( QListViewItem * ); + void slotDoubleUpButtonClicked(); + void slotUpButtonClicked(); + void slotDownButtonClicked(); + void slotDoubleDownButtonClicked(); + void slotLeftButtonClicked(); + void slotRightButtonClicked(); + + private: + void takePlaceHolderItem(); + void enableDisableButtons( QListViewItem * ); + + private: + class Private; + Private * d; + protected: + virtual void virtual_hook( int, void* ); }; } -#endif // __KLEO_SPECIALJOB_H__ +#endif // __KLEO_UI_DNATTRIBUTEORDERCONFIGWIDGET_H__ diff --git a/lib/ui/keyapprovaldialog.cpp b/lib/ui/keyapprovaldialog.cpp new file mode 100644 index 000000000..7af85a0bb --- /dev/null +++ b/lib/ui/keyapprovaldialog.cpp @@ -0,0 +1,227 @@ +/* -*- c++ -*- + keyapprovaldialog.h + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Based on kpgpui.h + Copyright (C) 2001,2002 the KPGP authors + See file libkdenetwork/AUTHORS.kpgp for details + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "keyapprovaldialog.h" + +#include "keyrequester.h" + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +static Kleo::EncryptionPreference cb2pref( int i ) { + switch ( i ) { + default: + case 0: return Kleo::UnknownPreference; + case 1: return Kleo::NeverEncrypt; + case 2: return Kleo::AlwaysEncrypt; + case 3: return Kleo::AlwaysEncryptIfPossible; + case 4: return Kleo::AlwaysAskForEncryption; + case 5: return Kleo::AskWheneverPossible; + } +} + +static int pref2cb( Kleo::EncryptionPreference p ) { + switch ( p ) { + default: return 0; + case Kleo::NeverEncrypt: return 1; + case Kleo::AlwaysEncrypt: return 2; + case Kleo::AlwaysEncryptIfPossible: return 3; + case Kleo::AlwaysAskForEncryption: return 4; + case Kleo::AskWheneverPossible: return 5; + } +} + +static QStringList preferencesStrings() { + return QStringList() << i18n("") + << i18n("Never Encrypt with This Key") + << i18n("Always Encrypt with This Key") + << i18n("Encrypt Whenever Encryption is Possible") + << i18n("Always Ask") + << i18n("Ask Whenever Encryption is Possible"); +} + + +struct Kleo::KeyApprovalDialog::Private { + Private() : selfRequester( 0 ), prefsChanged( false ) {} + + Kleo::KeyRequester * selfRequester; + QStringList addresses; + std::vector requesters; + std::vector preferences; + bool prefsChanged; +}; + +Kleo::KeyApprovalDialog::KeyApprovalDialog( const std::vector & recipients, + const std::vector & sender, + QWidget * parent, const char * name, + bool modal ) + : KDialogBase( parent, name, modal, i18n("Encryption Key Approval"), Ok|Cancel, Ok ), + d( 0 ) +{ + assert( !recipients.empty() ); + + d = new Private(); + + QFrame *page = makeMainWidget(); + QVBoxLayout * vlay = new QVBoxLayout( page, 0, spacingHint() ); + + vlay->addWidget( new QLabel( i18n("The following keys will be used for encryption:"), page ) ); + + QScrollView * sv = new QScrollView( page ); + sv->setResizePolicy( QScrollView::AutoOneFit ); + vlay->addWidget( sv ); + + QWidget * view = new QWidget( sv->viewport() ); + + QGridLayout * glay = new QGridLayout( view, 3, 2, marginHint(), spacingHint() ); + glay->setColStretch( 1, 1 ); + sv->addChild( view ); + + int row = -1; + + if ( !sender.empty() ) { + ++row; + glay->addWidget( new QLabel( i18n("Your keys:"), view ), row, 0 ); + d->selfRequester = new EncryptionKeyRequester( true, EncryptionKeyRequester::AllProtocols, view ); + d->selfRequester->setKeys( sender ); + glay->addWidget( d->selfRequester, row, 1 ); + ++row; + glay->addMultiCellWidget( new KSeparator( Horizontal, view ), row, row, 0, 1 ); + } + + const QStringList prefs = preferencesStrings(); + + for ( std::vector::const_iterator it = recipients.begin() ; it != recipients.end() ; ++it ) { + ++row; + glay->addWidget( new QLabel( i18n("Recipient:"), view ), row, 0 ); + glay->addWidget( new QLabel( it->address, view ), row, 1 ); + d->addresses.push_back( it->address ); + + ++row; + glay->addWidget( new QLabel( i18n("Encryption keys:"), view ), row, 0 ); + KeyRequester * req = new EncryptionKeyRequester( true, EncryptionKeyRequester::AllProtocols, view ); + req->setKeys( it->keys ); + glay->addWidget( req, row, 1 ); + d->requesters.push_back( req ); + + ++row; + glay->addWidget( new QLabel( i18n("Encryption preference:"), view ), row, 0 ); + QComboBox * cb = new QComboBox( false, view ); + cb->insertStringList( prefs ); + glay->addWidget( cb, row, 1 ); + cb->setCurrentItem( pref2cb( it->pref ) ); + connect( cb, SIGNAL(activated(int)), SLOT(slotPrefsChanged()) ); + d->preferences.push_back( cb ); + } + + // calculate the optimal width for the dialog + const int dialogWidth = marginHint() + + sv->frameWidth() + + view->sizeHint().width() + + sv->verticalScrollBar()->sizeHint().width() + + sv->frameWidth() + + marginHint() + + 2; + // calculate the optimal height for the dialog + const int dialogHeight = marginHint() + + fontMetrics().height() + + spacingHint() + + sv->frameWidth() + + view->sizeHint().height() + + sv->horizontalScrollBar()->sizeHint().height() + + sv->frameWidth() + + spacingHint() + + actionButton( KDialogBase::Cancel )->sizeHint().height() + + marginHint() + + 2; + + // don't make the dialog too large + const QRect desk = KGlobalSettings::desktopGeometry( this ); + setInitialSize( QSize( kMin( dialogWidth, 3 * desk.width() / 4 ), + kMin( dialogHeight, 7 * desk.height() / 8 ) ) ); +} + +Kleo::KeyApprovalDialog::~KeyApprovalDialog() { + delete d; d = 0; +} + +std::vector Kleo::KeyApprovalDialog::senderKeys() const { + return d->selfRequester ? d->selfRequester->keys() : std::vector() ; +} + +std::vector Kleo::KeyApprovalDialog::items() const { + assert( d->requesters.size() == d->addresses.size() ); + assert( d->requesters.size() == d->preferences.size() ); + + std::vector result; + result.reserve( d->requesters.size() ); + QStringList::const_iterator ait = d->addresses.begin(); + std::vector::const_iterator rit = d->requesters.begin(); + std::vector::const_iterator cit = d->preferences.begin(); + while ( ait != d->addresses.end() ) + result.push_back( Item( *ait++, (*rit++)->keys(), cb2pref( (*cit++)->currentItem() ) ) ); + return result; +} + +bool Kleo::KeyApprovalDialog::preferencesChanged() const { + return d->prefsChanged; +} + +void Kleo::KeyApprovalDialog::slotPrefsChanged() { + d->prefsChanged = true; +} + +#include "keyapprovaldialog.moc" diff --git a/lib/ui/passphrasedialog.h b/lib/ui/keyapprovaldialog.h similarity index 53% copy from lib/ui/passphrasedialog.h copy to lib/ui/keyapprovaldialog.h index b53619509..224530a71 100644 --- a/lib/ui/passphrasedialog.h +++ b/lib/ui/keyapprovaldialog.h @@ -1,91 +1,92 @@ /* -*- c++ -*- - passphrasedialog.h + keyselectiondialog.h This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004 Klarälvdalens Datakonsult AB + Based on kpgpui.h + Copyright (C) 2001,2002 the KPGP authors + See file libkdenetwork/AUTHORS.kpgp for details + Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. +*/ +#ifndef __KLEO_KEYAPPROVALDIALOG_H__ +#define __KLEO_KEYAPPROVALDIALOG_H__ - Based on kpgpui.h - Copyright (C) 2001,2002 the KPGP authors - See file libkdenetwork/AUTHORS.kpgp for details +#include - This file is part of KPGP, the KDE PGP/GnuPG support library. +#include +#include - KPGP is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. +#include // for EncryptPref +#include - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA -*/ +#include -#ifndef __KLEO_UI_PASSPHRASEDIALOG_H__ -#define __KLEO_UI_PASSPHRASEDIALOG_H__ +namespace GpgME { + class Key; +} -#include +class QStringList; namespace Kleo { - class PassphraseDialog : public KDialogBase { + class KDE_EXPORT KeyApprovalDialog : public KDialogBase { Q_OBJECT public: - PassphraseDialog( const QString & description, - const QString & caption=QString::null, - QWidget * parent=0, const char * name=0, - bool modal=true ); - ~PassphraseDialog(); - - const char * passphrase() const; - - signals: - /** emitted when the user clicks Ok. \a pass is never NULL. - \c pass only valid inside slots connected to this signal. - */ - void finished( const char * pass ); - /** emitted when the user clicks Cancel. */ - void canceled(); - - protected slots: - /*! \reimp */ - void slotOk(); - /*! \reimp */ - void slotCancel(); + struct Item { + Item() : pref( UnknownPreference ) {} + Item( const QString & a, const std::vector & k, + EncryptionPreference p=UnknownPreference ) + : address( a ), keys( k ), pref( p ) {} + QString address; + std::vector keys; + EncryptionPreference pref; + }; + + KeyApprovalDialog( const std::vector & recipients, + const std::vector & sender, + QWidget * parent=0, const char * name=0, + bool modal=true ); + ~KeyApprovalDialog(); + + std::vector items() const; + std::vector senderKeys() const; + + bool preferencesChanged() const; + + private slots: + void slotPrefsChanged(); private: class Private; Private * d; - protected: - /*! \reimp */ - void virtual_hook( int, void* ); }; } // namespace Kleo -#endif // __KLEO_UI_PASSPHRASEDIALOG_H__ +#endif // __KLEO_KEYAPPROVALDIALOG_H__ diff --git a/lib/ui/keylistview.cpp b/lib/ui/keylistview.cpp new file mode 100644 index 000000000..98534a4b7 --- /dev/null +++ b/lib/ui/keylistview.cpp @@ -0,0 +1,869 @@ +/* + keylistview.cpp + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "keylistview.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +static const int updateDelayMilliSecs = 500; + +namespace { + + class ItemToolTip : public QToolTip { + public: + ItemToolTip( Kleo::KeyListView * parent ); + protected: + void maybeTip( const QPoint & p ); + private: + Kleo::KeyListView * mKeyListView; + }; + + ItemToolTip::ItemToolTip( Kleo::KeyListView * parent ) + : QToolTip( parent->viewport() ), mKeyListView( parent ) {} + + void ItemToolTip::maybeTip( const QPoint & p ) { + if ( !mKeyListView ) + return; + + const QListViewItem * item = mKeyListView->itemAt( p ); + if ( !item ) + return; + + const QRect itemRect = mKeyListView->itemRect( item ); + if ( !itemRect.isValid() ) + return; + + const int col = mKeyListView->header()->sectionAt( p.x() ); + if ( col == -1 ) + return; + + const QRect headerRect = mKeyListView->header()->sectionRect( col ); + if ( !headerRect.isValid() ) + return; + + const QRect cellRect( headerRect.left(), itemRect.top(), + headerRect.width(), itemRect.height() ); + + QString tipStr; + if ( const Kleo::KeyListViewItem * klvi = Kleo::lvi_cast( item ) ) + tipStr = klvi->toolTip( col ); + else + tipStr = item->text( col ) ; + + if ( !tipStr.isEmpty() ) + tip( cellRect, tipStr ); + } + +} // anon namespace + +struct Kleo::KeyListView::Private { + Private() : updateTimer( 0 ), itemToolTip( 0 ) {} + + std::vector keyBuffer; + QTimer * updateTimer; + QToolTip * itemToolTip; + std::map itemMap; +}; + +// a list of signals where we want to replace QListViewItem with +// Kleo:KeyListViewItem: +static const struct { + const char * source; + const char * target; +} signalReplacements[] = { + { SIGNAL(doubleClicked(QListViewItem*,const QPoint&,int)), + SLOT(slotEmitDoubleClicked(QListViewItem*,const QPoint&,int)) }, + { SIGNAL(returnPressed(QListViewItem*)), + SLOT(slotEmitReturnPressed(QListViewItem*)) }, + { SIGNAL(selectionChanged(QListViewItem*)), + SLOT(slotEmitSelectionChanged(QListViewItem*)) }, + { SIGNAL(contextMenu(KListView*, QListViewItem*,const QPoint&)), + SLOT(slotEmitContextMenu(KListView*, QListViewItem*,const QPoint&)) }, +}; +static const int numSignalReplacements = sizeof signalReplacements / sizeof *signalReplacements; + + +Kleo::KeyListView::KeyListView( const ColumnStrategy * columnStrategy, const DisplayStrategy * displayStrategy, QWidget * parent, const char * name, WFlags f ) + : KListView( parent, name ), + mColumnStrategy( columnStrategy ), + mDisplayStrategy ( displayStrategy ), + mHierarchical( false ) +{ + setWFlags( f ); + + d = new Private(); + + d->updateTimer = new QTimer( this ); + connect( d->updateTimer, SIGNAL(timeout()), SLOT(slotUpdateTimeout()) ); + + if ( !columnStrategy ) { + kdWarning(5150) << "Kleo::KeyListView: need a column strategy to work with!" << endl; + return; + } + + const QFontMetrics fm = fontMetrics(); + + for ( int col = 0 ; !columnStrategy->title( col ).isEmpty() ; ++col ) { + addColumn( columnStrategy->title( col ), columnStrategy->width( col, fm ) ); + setColumnWidthMode( col, columnStrategy->widthMode( col ) ); + } + + setAllColumnsShowFocus( true ); + setShowToolTips( false ); // we do it instead... + + for ( int i = 0 ; i < numSignalReplacements ; ++i ) + connect( this, signalReplacements[i].source, signalReplacements[i].target ); + + QToolTip::remove( this ); + QToolTip::remove( viewport() ); // make double sure :) + d->itemToolTip = new ItemToolTip( this ); +} + +Kleo::KeyListView::~KeyListView() { + d->updateTimer->stop(); + // need to clear here, since in ~QListView, our children won't have + // a valid listView() pointing to us anymore, and their dtors try to + // unregister from us. + clear(); + assert( d->itemMap.size() == 0 ); + // need to delete the tooltip ourselves, as ~QToolTip isn't virtual :o + delete d->itemToolTip; d->itemToolTip = 0; + delete d; d = 0; + delete mColumnStrategy; mColumnStrategy = 0; + delete mDisplayStrategy; mDisplayStrategy = 0; +} + +void Kleo::KeyListView::insertItem( QListViewItem * qlvi ) { + //kdDebug() << "Kleo::KeyListView::insertItem( " << qlvi << " )" << endl; + KListView::insertItem( qlvi ); + if ( KeyListViewItem * item = lvi_cast( qlvi ) ) + registerItem( item ); +} + +void Kleo::KeyListView::takeItem( QListViewItem * qlvi ) { + //kdDebug() << "Kleo::KeyListView::takeItem( " << qlvi << " )" << endl; + if ( KeyListViewItem * item = lvi_cast( qlvi ) ) + deregisterItem( item ); + KListView::takeItem( qlvi ); +} + + +void Kleo::KeyListView::setHierarchical( bool hier ) { + if ( hier == mHierarchical ) + return; + mHierarchical = hier; + if ( hier ) + gatherScattered(); + else + scatterGathered( firstChild() ); +} + +void Kleo::KeyListView::slotAddKey( const GpgME::Key & key ) { + if ( key.isNull() ) + return; + + d->keyBuffer.push_back( key ); + if ( !d->updateTimer->isActive() ) + d->updateTimer->start( updateDelayMilliSecs, true /* single-shot */ ); +} + +void Kleo::KeyListView::slotUpdateTimeout() { + if ( d->keyBuffer.empty() ) + return; + + const bool wasUpdatesEnabled = viewport()->isUpdatesEnabled(); + if ( wasUpdatesEnabled ) + viewport()->setUpdatesEnabled( false ); + kdDebug( 5150 ) << "Kleo::KeyListView::slotUpdateTimeout(): processing " + << d->keyBuffer.size() << " items en block" << endl; + if ( hierarchical() ) { + for ( std::vector::const_iterator it = d->keyBuffer.begin() ; it != d->keyBuffer.end() ; ++it ) + doHierarchicalInsert( *it ); + gatherScattered(); + } else { + for ( std::vector::const_iterator it = d->keyBuffer.begin() ; it != d->keyBuffer.end() ; ++it ) + (void)new KeyListViewItem( this, *it ); + } + if ( wasUpdatesEnabled ) + viewport()->setUpdatesEnabled( true ); + d->keyBuffer.clear(); +} + +void Kleo::KeyListView::clear() { + d->updateTimer->stop(); + d->keyBuffer.clear(); + KListView::clear(); +} + +void Kleo::KeyListView::registerItem( KeyListViewItem * item ) { + //kdDebug() << "registerItem( " << item << " )" << endl; + if ( !item ) + return; + const QCString fpr = item->key().primaryFingerprint(); + if ( !fpr.isEmpty() ) + d->itemMap.insert( std::make_pair( fpr, item ) ); +} + +void Kleo::KeyListView::deregisterItem( const KeyListViewItem * item ) { + //kdDebug() << "deregisterItem( KeyLVI: " << item << " )" << endl; + if ( !item ) + return; + std::map::iterator it + = d->itemMap.find( item->key().primaryFingerprint() ); + if ( it == d->itemMap.end() ) + return; + Q_ASSERT( it->second == item ); + if ( it->second != item ) + return; + d->itemMap.erase( it ); +} + +void Kleo::KeyListView::doHierarchicalInsert( const GpgME::Key & key ) { + const QCString fpr = key.primaryFingerprint(); + if ( fpr.isEmpty() ) + return; + KeyListViewItem * item = 0; + if ( !key.isRoot() ) + if ( KeyListViewItem * parent = itemByFingerprint( key.chainID() ) ) { + item = new KeyListViewItem( parent, key ); + parent->setOpen( true ); + } + if ( !item ) + item = new KeyListViewItem( this, key ); // top-level (for now) + + d->itemMap.insert( std::make_pair( fpr, item ) ); +} + +void Kleo::KeyListView::gatherScattered() { + KeyListViewItem * item = firstChild(); + while ( item ) { + KeyListViewItem * cur = item; + item = item->nextSibling(); + if ( cur->key().isRoot() ) + continue; + if ( KeyListViewItem * parent = itemByFingerprint( cur->key().chainID() ) ) { + // found a new parent... + // ### todo: optimize by suppressing removing/adding the item to the itemMap... + takeItem( cur ); + parent->insertItem( cur ); + parent->setOpen( true ); + } + } +} + +void Kleo::KeyListView::scatterGathered( QListViewItem * start ) { + QListViewItem * item = start; + while ( item ) { + QListViewItem * cur = item; + item = item->nextSibling(); + + scatterGathered( cur->firstChild() ); + assert( cur->childCount() == 0 ); + + // ### todo: optimize by suppressing removing/adding the item to the itemMap... + if ( cur->parent() ) + cur->parent()->takeItem( cur ); + else + takeItem( cur ); + insertItem( cur ); + } +} + +Kleo::KeyListViewItem * Kleo::KeyListView::itemByFingerprint( const QCString & s ) const { + if ( s.isEmpty() ) + return 0; + const std::map::const_iterator it = d->itemMap.find( s ); + if ( it == d->itemMap.end() ) + return 0; + return it->second; +} + + +void Kleo::KeyListView::slotRefreshKey( const GpgME::Key & key ) { + const char * fpr = key.primaryFingerprint(); + if ( !fpr ) + return; + if ( KeyListViewItem * item = itemByFingerprint( fpr ) ) + item->setKey ( key ); + else + // none found -> add it + slotAddKey( key ); +} + +// slots for the emission of covariant signals: + +void Kleo::KeyListView::slotEmitDoubleClicked( QListViewItem * item, const QPoint & p, int col ) { + if ( !item || lvi_cast( item ) ) + emit doubleClicked( static_cast( item ), p, col ); +} + +void Kleo::KeyListView::slotEmitReturnPressed( QListViewItem * item ) { + if ( !item || lvi_cast( item ) ) + emit returnPressed( static_cast( item ) ); +} + +void Kleo::KeyListView::slotEmitSelectionChanged( QListViewItem * item ) { + if ( !item || lvi_cast( item ) ) + emit selectionChanged( static_cast( item ) ); +} + +void Kleo::KeyListView::slotEmitContextMenu( KListView*, QListViewItem * item, const QPoint & p ) { + if ( !item || lvi_cast( item ) ) + emit contextMenu( static_cast( item ), p ); +} + +// +// +// KeyListViewItem +// +// + +Kleo::KeyListViewItem::KeyListViewItem( KeyListView * parent, const GpgME::Key & key ) + : QListViewItem( parent ) +{ + setKey( key ); +} + +Kleo::KeyListViewItem::KeyListViewItem( KeyListView * parent, KeyListViewItem * after, const GpgME::Key & key ) + : QListViewItem( parent, after ) +{ + setKey( key ); +} + +Kleo::KeyListViewItem::KeyListViewItem( KeyListViewItem * parent, const GpgME::Key & key ) + : QListViewItem( parent ) +{ + setKey( key ); +} + +Kleo::KeyListViewItem::KeyListViewItem( KeyListViewItem * parent, KeyListViewItem * after, const GpgME::Key & key ) + : QListViewItem( parent, after ) +{ + setKey( key ); +} + +Kleo::KeyListViewItem::~KeyListViewItem() { + // delete the children first... When children are deleted in the + // QLVI dtor, they don't have listView() anymore, thus they don't + // call deregister( this ), leading to stale entries in the + // itemMap... + while ( QListViewItem * item = firstChild() ) + delete item; + // better do this here, too, since deletion is top-down and thus + // we're deleted when our parent item is no longer a + // KeyListViewItem, but a mere QListViewItem, so our takeItem() + // overload is gone by that time... + if ( KeyListView * lv = listView() ) + lv->deregisterItem( this ); +} + +void Kleo::KeyListViewItem::setKey( const GpgME::Key & key ) { + KeyListView * lv = listView(); + if ( lv ) + lv->deregisterItem( this ); + mKey = key; + if ( lv ) + lv->registerItem( this ); + + // the ColumnStrategy operations might be very slow, so cache their + // result here, where we're non-const :) + const Kleo::KeyListView::ColumnStrategy * cs = lv ? lv->columnStrategy() : 0 ; + if ( !cs ) + return; + const int numCols = lv ? lv->columns() : 0 ; + for ( int i = 0 ; i < numCols ; ++i ) { + setText( i, cs->text( key, i ) ); + if ( const QPixmap * pix = cs->pixmap( key, i ) ) + setPixmap( i, *pix ); + } + repaint(); +} + +QString Kleo::KeyListViewItem::toolTip( int col ) const { + return listView() && listView()->columnStrategy() + ? listView()->columnStrategy()->toolTip( key(), col ) + : QString::null ; +} + +int Kleo::KeyListViewItem::compare( QListViewItem * item, int col, bool ascending ) const { + if ( !item || item->rtti() != RTTI || !listView() || !listView()->columnStrategy() ) + return QListViewItem::compare( item, col, ascending ); + KeyListViewItem * that = static_cast( item ); + return listView()->columnStrategy()->compare( this->key(), that->key(), col ); +} + +void Kleo::KeyListViewItem::paintCell( QPainter * p, const QColorGroup & cg, int column, int width, int alignment ) { + const KeyListView::DisplayStrategy * ds = listView() ? listView()->displayStrategy() : 0 ; + if ( !ds ) { + QListViewItem::paintCell( p, cg, column, width, alignment ); + return; + } + const QColor fg = ds->keyForeground( key(), cg.text() ); + const QColor bg = ds->keyBackground( key(), cg.base() ); + const QFont f = ds->keyFont( key(), p->font() ); + + QColorGroup _cg = cg; + p->setFont( f ); + _cg.setColor( QColorGroup::Text, fg ); + _cg.setColor( QColorGroup::Base, bg ); + + QListViewItem::paintCell( p, _cg, column, width, alignment ); +} + +void Kleo::KeyListViewItem::insertItem( QListViewItem * qlvi ) { + //kdDebug() << "Kleo::KeyListViewItem::insertItem( " << qlvi << " )" << endl; + QListViewItem::insertItem( qlvi ); + if ( KeyListViewItem * item = lvi_cast( qlvi ) ) + listView()->registerItem( item ); +} + +void Kleo::KeyListViewItem::takeItem( QListViewItem * qlvi ) { + //kdDebug() << "Kleo::KeyListViewItem::takeItem( " << qlvi << " )" << endl; + if ( KeyListViewItem * item = lvi_cast( qlvi ) ) + listView()->deregisterItem( item ); + QListViewItem::takeItem( qlvi ); +} + + +// +// +// SubkeyKeyListViewItem +// +// + +Kleo::SubkeyKeyListViewItem::SubkeyKeyListViewItem( KeyListView * parent, const GpgME::Subkey & subkey ) + : KeyListViewItem( parent, subkey.parent() ), mSubkey( subkey ) +{ + +} + +Kleo::SubkeyKeyListViewItem::SubkeyKeyListViewItem( KeyListView * parent, KeyListViewItem * after, const GpgME::Subkey & subkey ) + : KeyListViewItem( parent, after, subkey.parent() ), mSubkey( subkey ) +{ + +} + +Kleo::SubkeyKeyListViewItem::SubkeyKeyListViewItem( KeyListViewItem * parent, const GpgME::Subkey & subkey ) + : KeyListViewItem( parent, subkey.parent() ), mSubkey( subkey ) +{ + +} + +Kleo::SubkeyKeyListViewItem::SubkeyKeyListViewItem( KeyListViewItem * parent, KeyListViewItem * after, const GpgME::Subkey & subkey ) + : KeyListViewItem( parent, after, subkey.parent() ), mSubkey( subkey ) +{ + +} + +void Kleo::SubkeyKeyListViewItem::setSubkey( const GpgME::Subkey & subkey ) { + mSubkey = subkey; + setKey( subkey.parent() ); +} + +QString Kleo::SubkeyKeyListViewItem::text( int col ) const { + return listView() && listView()->columnStrategy() + ? listView()->columnStrategy()->subkeyText( subkey(), col ) + : QString::null ; +} + +QString Kleo::SubkeyKeyListViewItem::toolTip( int col ) const { + return listView() && listView()->columnStrategy() + ? listView()->columnStrategy()->subkeyToolTip( subkey(), col ) + : QString::null ; +} + +const QPixmap * Kleo::SubkeyKeyListViewItem::pixmap( int col ) const { + return listView() && listView()->columnStrategy() + ? listView()->columnStrategy()->subkeyPixmap( subkey(), col ) : 0 ; +} + +int Kleo::SubkeyKeyListViewItem::compare( QListViewItem * item, int col, bool ascending ) const { + if ( !item || item->rtti() != RTTI || !listView() || !listView()->columnStrategy() ) + return KeyListViewItem::compare( item, col, ascending ); + SubkeyKeyListViewItem * that = static_cast( item ); + return listView()->columnStrategy()->subkeyCompare( this->subkey(), that->subkey(), col ); +} + +void Kleo::SubkeyKeyListViewItem::paintCell( QPainter * p, const QColorGroup & cg, int column, int width, int alignment ) { + const KeyListView::DisplayStrategy * ds = listView() ? listView()->displayStrategy() : 0 ; + if ( !ds ) { + QListViewItem::paintCell( p, cg, column, width, alignment ); + return; + } + const QColor fg = ds->subkeyForeground( subkey(), cg.text() ); + const QColor bg = ds->subkeyBackground( subkey(), cg.base() ); + const QFont f = ds->subkeyFont( subkey(), p->font() ); + + QColorGroup _cg = cg; + p->setFont( f ); + _cg.setColor( QColorGroup::Text, fg ); + _cg.setColor( QColorGroup::Base, bg ); + + QListViewItem::paintCell( p, _cg, column, width, alignment ); +} + + +// +// +// UserIDKeyListViewItem +// +// + +Kleo::UserIDKeyListViewItem::UserIDKeyListViewItem( KeyListView * parent, const GpgME::UserID & userID ) + : KeyListViewItem( parent, userID.parent() ), mUserID( userID ) +{ + +} + +Kleo::UserIDKeyListViewItem::UserIDKeyListViewItem( KeyListView * parent, KeyListViewItem * after, const GpgME::UserID & userID ) + : KeyListViewItem( parent, after, userID.parent() ), mUserID( userID ) +{ + +} + +Kleo::UserIDKeyListViewItem::UserIDKeyListViewItem( KeyListViewItem * parent, const GpgME::UserID & userID ) + : KeyListViewItem( parent, userID.parent() ), mUserID( userID ) +{ + +} + +Kleo::UserIDKeyListViewItem::UserIDKeyListViewItem( KeyListViewItem * parent, KeyListViewItem * after, const GpgME::UserID & userID ) + : KeyListViewItem( parent, after, userID.parent() ), mUserID( userID ) +{ + +} + +void Kleo::UserIDKeyListViewItem::setUserID( const GpgME::UserID & userID ) { + mUserID = userID; + setKey( userID.parent() ); +} + +QString Kleo::UserIDKeyListViewItem::text( int col ) const { + return listView() && listView()->columnStrategy() + ? listView()->columnStrategy()->userIDText( userID(), col ) + : QString::null ; +} + +QString Kleo::UserIDKeyListViewItem::toolTip( int col ) const { + return listView() && listView()->columnStrategy() + ? listView()->columnStrategy()->userIDToolTip( userID(), col ) + : QString::null ; +} + +const QPixmap * Kleo::UserIDKeyListViewItem::pixmap( int col ) const { + return listView() && listView()->columnStrategy() + ? listView()->columnStrategy()->userIDPixmap( userID(), col ) : 0 ; +} + +int Kleo::UserIDKeyListViewItem::compare( QListViewItem * item, int col, bool ascending ) const { + if ( !item || item->rtti() != RTTI || !listView() || !listView()->columnStrategy() ) + return KeyListViewItem::compare( item, col, ascending ); + UserIDKeyListViewItem * that = static_cast( item ); + return listView()->columnStrategy()->userIDCompare( this->userID(), that->userID(), col ); +} + + +void Kleo::UserIDKeyListViewItem::paintCell( QPainter * p, const QColorGroup & cg, int column, int width, int alignment ) { + const KeyListView::DisplayStrategy * ds = listView() ? listView()->displayStrategy() : 0 ; + if ( !ds ) { + QListViewItem::paintCell( p, cg, column, width, alignment ); + return; + } + const QColor fg = ds->useridForeground( userID(), cg.text() ); + const QColor bg = ds->useridBackground( userID(), cg.base() ); + const QFont f = ds->useridFont( userID(), p->font() ); + + QColorGroup _cg = cg; + p->setFont( f ); + _cg.setColor( QColorGroup::Text, fg ); + _cg.setColor( QColorGroup::Base, bg ); + + QListViewItem::paintCell( p, _cg, column, width, alignment ); +} + + +// +// +// SignatureKeyListViewItem +// +// + +Kleo::SignatureKeyListViewItem::SignatureKeyListViewItem( KeyListView * parent, const GpgME::UserID::Signature & signature ) + : KeyListViewItem( parent, signature.parent().parent() ), mSignature( signature ) +{ + +} + +Kleo::SignatureKeyListViewItem::SignatureKeyListViewItem( KeyListView * parent, KeyListViewItem * after, const GpgME::UserID::Signature & signature ) + : KeyListViewItem( parent, after, signature.parent().parent() ), mSignature( signature ) +{ + +} + +Kleo::SignatureKeyListViewItem::SignatureKeyListViewItem( KeyListViewItem * parent, const GpgME::UserID::Signature & signature ) + : KeyListViewItem( parent, signature.parent().parent() ), mSignature( signature ) +{ + +} + +Kleo::SignatureKeyListViewItem::SignatureKeyListViewItem( KeyListViewItem * parent, KeyListViewItem * after, const GpgME::UserID::Signature & signature ) + : KeyListViewItem( parent, after, signature.parent().parent() ), mSignature( signature ) +{ + +} + +void Kleo::SignatureKeyListViewItem::setSignature( const GpgME::UserID::Signature & signature ) { + mSignature = signature; + setKey( signature.parent().parent() ); +} + +QString Kleo::SignatureKeyListViewItem::text( int col ) const { + return listView() && listView()->columnStrategy() + ? listView()->columnStrategy()->signatureText( signature(), col ) + : QString::null ; +} + +QString Kleo::SignatureKeyListViewItem::toolTip( int col ) const { + return listView() && listView()->columnStrategy() + ? listView()->columnStrategy()->signatureToolTip( signature(), col ) + : QString::null ; +} + +const QPixmap * Kleo::SignatureKeyListViewItem::pixmap( int col ) const { + return listView() && listView()->columnStrategy() + ? listView()->columnStrategy()->signaturePixmap( signature(), col ) : 0 ; +} + +int Kleo::SignatureKeyListViewItem::compare( QListViewItem * item, int col, bool ascending ) const { + if ( !item || item->rtti() != RTTI || !listView() || !listView()->columnStrategy() ) + return KeyListViewItem::compare( item, col, ascending ); + SignatureKeyListViewItem * that = static_cast( item ); + return listView()->columnStrategy()->signatureCompare( this->signature(), that->signature(), col ); +} + +void Kleo::SignatureKeyListViewItem::paintCell( QPainter * p, const QColorGroup & cg, int column, int width, int alignment ) { + const KeyListView::DisplayStrategy * ds = listView() ? listView()->displayStrategy() : 0 ; + if ( !ds ) { + QListViewItem::paintCell( p, cg, column, width, alignment ); + return; + } + const QColor fg = ds->signatureForeground( signature(), cg.text() ); + const QColor bg = ds->signatureBackground( signature(), cg.base() ); + const QFont f = ds->signatureFont( signature(), p->font() ); + + QColorGroup _cg = cg; + p->setFont( f ); + _cg.setColor( QColorGroup::Text, fg ); + _cg.setColor( QColorGroup::Base, bg ); + + QListViewItem::paintCell( p, _cg, column, width, alignment ); +} + + +// +// +// ColumnStrategy +// +// + +Kleo::KeyListView::ColumnStrategy::~ColumnStrategy() {} + +int Kleo::KeyListView::ColumnStrategy::compare( const GpgME::Key & key1, const GpgME::Key & key2, int col ) const { + return QString::localeAwareCompare( text( key1, col ), text( key2, col ) ); +} + +int Kleo::KeyListView::ColumnStrategy::width( int col, const QFontMetrics & fm ) const { + return fm.width( title( col ) ) * 2; +} + +int Kleo::KeyListView::ColumnStrategy::subkeyCompare( const GpgME::Subkey & sub1, const GpgME::Subkey & sub2, int col ) const { + return QString::localeAwareCompare( subkeyText( sub1, col ), subkeyText( sub2, col ) ); +} + +int Kleo::KeyListView::ColumnStrategy::userIDCompare( const GpgME::UserID & uid1, const GpgME::UserID & uid2, int col ) const { + return QString::localeAwareCompare( userIDText( uid1, col ), userIDText( uid2, col ) ); +} + +int Kleo::KeyListView::ColumnStrategy::signatureCompare( const GpgME::UserID::Signature & sig1, const GpgME::UserID::Signature & sig2, int col ) const { + return QString::localeAwareCompare( signatureText( sig1, col ), signatureText( sig2, col ) ); +} + +QString Kleo::KeyListView::ColumnStrategy::toolTip( const GpgME::Key & key, int col ) const { + return text( key, col ); +} + +QString Kleo::KeyListView::ColumnStrategy::subkeyToolTip( const GpgME::Subkey & sub, int col ) const { + return subkeyText( sub, col ); +} + +QString Kleo::KeyListView::ColumnStrategy::userIDToolTip( const GpgME::UserID & uid, int col ) const { + return userIDText( uid, col ); +} + +QString Kleo::KeyListView::ColumnStrategy::signatureToolTip( const GpgME::UserID::Signature & sig, int col ) const { + return signatureText( sig, col ); +} + +// +// +// DisplayStrategy +// +// + +Kleo::KeyListView::DisplayStrategy::~DisplayStrategy() {} + + +//font +QFont Kleo::KeyListView::DisplayStrategy::keyFont( const GpgME::Key &, const QFont & font ) const { + return font; +} + +QFont Kleo::KeyListView::DisplayStrategy::subkeyFont( const GpgME::Subkey &, const QFont & font ) const { + return font; +} + +QFont Kleo::KeyListView::DisplayStrategy::useridFont( const GpgME::UserID &, const QFont & font ) const { + return font; +} + +QFont Kleo::KeyListView::DisplayStrategy::signatureFont( const GpgME::UserID::Signature &, const QFont & font ) const { + return font; +} + +//foreground +QColor Kleo::KeyListView::DisplayStrategy::keyForeground( const GpgME::Key &, const QColor & fg )const { + return fg; +} + +QColor Kleo::KeyListView::DisplayStrategy::subkeyForeground( const GpgME::Subkey &, const QColor & fg ) const { + return fg; +} + +QColor Kleo::KeyListView::DisplayStrategy::useridForeground( const GpgME::UserID &, const QColor & fg ) const { + return fg; +} + +QColor Kleo::KeyListView::DisplayStrategy::signatureForeground( const GpgME::UserID::Signature &, const QColor & fg ) const { + return fg; +} + +//background +QColor Kleo::KeyListView::DisplayStrategy::keyBackground( const GpgME::Key &, const QColor & bg )const { + return bg; +} + +QColor Kleo::KeyListView::DisplayStrategy::subkeyBackground( const GpgME::Subkey &, const QColor & bg ) const { + return bg; +} + +QColor Kleo::KeyListView::DisplayStrategy::useridBackground( const GpgME::UserID &, const QColor & bg ) const { + return bg; +} + +QColor Kleo::KeyListView::DisplayStrategy::signatureBackground( const GpgME::UserID::Signature &, const QColor & bg ) const { + return bg; +} + + +// +// +// Collection of covariant return reimplementations of QListView(Item) +// members: +// +// + +Kleo::KeyListView * Kleo::KeyListViewItem::listView() const { + return static_cast( QListViewItem::listView() ); +} + +Kleo::KeyListViewItem * Kleo::KeyListViewItem::nextSibling() const { + return static_cast( QListViewItem::nextSibling() ); +} + +Kleo::KeyListViewItem * Kleo::KeyListView::firstChild() const { + return static_cast( KListView::firstChild() ); +} + +Kleo::KeyListViewItem * Kleo::KeyListView::selectedItem() const { + return static_cast( KListView::selectedItem() ); +} + +static void selectedItems( QPtrList & result, QListViewItem * start ) { + for ( QListViewItem * item = start ; item ; item = item->nextSibling() ) { + if ( item->isSelected() ) + if ( Kleo::KeyListViewItem * i = Kleo::lvi_cast( item ) ) + result.append( i ); + selectedItems( result, item->firstChild() ); + } +} + +QPtrList Kleo::KeyListView::selectedItems() const { + QPtrList result; + ::selectedItems( result, firstChild() ); + return result; +} + +static bool hasSelection( QListViewItem * start ) { + for ( QListViewItem * item = start ; item ; item = item->nextSibling() ) + if ( item->isSelected() || hasSelection( item->firstChild() ) ) + return true; + return false; +} + +bool Kleo::KeyListView::hasSelection() const { + return ::hasSelection( firstChild() ); +} + +#include "keylistview.moc" diff --git a/lib/ui/keylistview.h b/lib/ui/keylistview.h new file mode 100644 index 000000000..3ef708771 --- /dev/null +++ b/lib/ui/keylistview.h @@ -0,0 +1,323 @@ +/* + keylistview.h + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifndef __KLEO_KEYLISTVIEW_H__ +#define __KLEO_KEYLISTVIEW_H__ + +#include + +#include +#include + +class QPainter; +class QColorGroup; +class QFont; +class QColor; + +namespace Kleo { + + // work around moc parser bug... +#define TEMPLATE_TYPENAME(T) template + TEMPLATE_TYPENAME(T) + inline T * lvi_cast( QListViewItem * item ) { + return item && (item->rtti() & T::RTTI_MASK) == T::RTTI + ? static_cast( item ) : 0 ; + } + + TEMPLATE_TYPENAME(T) + inline const T * lvi_cast( const QListViewItem * item ) { + return item && (item->rtti() & T::RTTI_MASK) == T::RTTI + ? static_cast( item ) : 0 ; + } +#undef TEMPLATE_TYPENAME + + class KeyListView; + + class KDE_EXPORT KeyListViewItem : public QListViewItem { + public: + KeyListViewItem( KeyListView * parent, const GpgME::Key & key ); + KeyListViewItem( KeyListView * parent, KeyListViewItem * after, const GpgME::Key & key ); + KeyListViewItem( KeyListViewItem * parent, const GpgME::Key & key ); + KeyListViewItem( KeyListViewItem * parent, KeyListViewItem * after, const GpgME::Key & key ); + ~KeyListViewItem(); + + void setKey( const GpgME::Key & key ); + const GpgME::Key & key() const { return mKey; } + + enum { RTTI_MASK = 0xFFFFFFF0, RTTI = 0x2C1362E0 }; + + // + // only boring stuff below: + // + virtual QString toolTip( int column ) const; + + /*! \reimp for covariant return */ + KeyListView * listView() const; + /*! \reimp for covariant return */ + KeyListViewItem * nextSibling() const; + /*! \reimp */ + int compare( QListViewItem * other, int col, bool ascending ) const; + /*! \reimp to allow for key() overload above */ + QString key( int col, bool ascending ) const { return QListViewItem::key( col, ascending ); } + /*! \reimp */ + int rtti() const { return RTTI; } + /*! \reimp */ + void paintCell( QPainter * p, const QColorGroup & cg, int column, int width, int alignment ); + /*! \reimp */ + void insertItem( QListViewItem * item ); + /*! \reimp */ + void takeItem( QListViewItem * item ); + + private: + GpgME::Key mKey; + }; + + class KDE_EXPORT SubkeyKeyListViewItem : public KeyListViewItem { + public: + SubkeyKeyListViewItem( KeyListView * parent, const GpgME::Subkey & subkey ); + SubkeyKeyListViewItem( KeyListView * parent, KeyListViewItem * after, const GpgME::Subkey & subkey ); + SubkeyKeyListViewItem( KeyListViewItem * parent, const GpgME::Subkey & subkey ); + SubkeyKeyListViewItem( KeyListViewItem * parent, KeyListViewItem * after, const GpgME::Subkey & subkey ); + + void setSubkey( const GpgME::Subkey & subkey ); + const GpgME::Subkey & subkey() const { return mSubkey; } + + enum { RTTI = KeyListViewItem::RTTI + 1 }; + + // + // only boring stuff below: + // + /*! \reimp */ + QString toolTip( int col ) const; + /*! \reimp */ + QString text( int col ) const; + /*! \reimp */ + const QPixmap * pixmap( int col ) const; + /*! \reimp */ + int compare( QListViewItem * other, int col, bool ascending ) const; + /*! \reimp */ + int rtti() const { return RTTI; } + /*! \reimp */ + void paintCell( QPainter * p, const QColorGroup & cg, int column, int width, int alignment ); + + private: + GpgME::Subkey mSubkey; + }; + + class KDE_EXPORT UserIDKeyListViewItem : public KeyListViewItem { + public: + UserIDKeyListViewItem( KeyListView * parent, const GpgME::UserID & userid ); + UserIDKeyListViewItem( KeyListView * parent, KeyListViewItem * after, const GpgME::UserID & userid ); + UserIDKeyListViewItem( KeyListViewItem * parent, const GpgME::UserID & userid ); + UserIDKeyListViewItem( KeyListViewItem * parent, KeyListViewItem * after, const GpgME::UserID & userid ); + + void setUserID( const GpgME::UserID & userid ); + const GpgME::UserID userID() const { return mUserID; } + + enum { RTTI = KeyListViewItem::RTTI + 2 }; + + // + // only boring stuff below: + // + /*! \reimp */ + QString toolTip( int col ) const; + /*! \reimp */ + QString text( int col ) const; + /*! \reimp */ + const QPixmap * pixmap( int col ) const; + /*! \reimp */ + int compare( QListViewItem * other, int col, bool ascending ) const; + /*! \reimp */ + int rtti() const { return RTTI; } + /*! \reimp */ + void paintCell( QPainter * p, const QColorGroup & cg, int column, int width, int alignment ); + + private: + GpgME::UserID mUserID; + }; + + class KDE_EXPORT SignatureKeyListViewItem : public KeyListViewItem { + public: + SignatureKeyListViewItem( KeyListView * parent, const GpgME::UserID::Signature & sig ); + SignatureKeyListViewItem( KeyListView * parent, KeyListViewItem * after, const GpgME::UserID::Signature & sig ); + SignatureKeyListViewItem( KeyListViewItem * parent, const GpgME::UserID::Signature & sig ); + SignatureKeyListViewItem( KeyListViewItem * parent, KeyListViewItem * after, const GpgME::UserID::Signature & sig ); + + void setSignature( const GpgME::UserID::Signature & sig ); + const GpgME::UserID::Signature & signature() const { return mSignature; } + + enum { RTTI = KeyListViewItem::RTTI + 3 }; + + // + // only boring stuff below: + // + /*! \reimp */ + QString toolTip( int col ) const; + /*! \reimp */ + QString text( int col ) const; + /*! \reimp */ + const QPixmap * pixmap( int col ) const; + /*! \reimp */ + int compare( QListViewItem * other, int col, bool ascending ) const; + /*! \reimp */ + int rtti() const { return RTTI; } + /*! \reimp */ + void paintCell( QPainter * p, const QColorGroup & cg, int column, int width, int alignment ); + + private: + GpgME::UserID::Signature mSignature; + }; + + + class KDE_EXPORT KeyListView : public KListView { + Q_OBJECT + friend class KeyListViewItem; + public: + + class KDE_EXPORT ColumnStrategy { + public: + virtual ~ColumnStrategy(); + virtual QString title( int column ) const = 0; + virtual int width( int column, const QFontMetrics & fm ) const; + virtual QListView::WidthMode widthMode( int ) const { return QListView::Manual; } + + virtual QString text( const GpgME::Key & key, int column ) const = 0; + virtual QString toolTip( const GpgME::Key & key, int column ) const; + virtual const QPixmap * pixmap( const GpgME::Key &, int ) const { return 0; } + virtual int compare( const GpgME::Key & key1, const GpgME::Key & key2, const int column ) const; + + virtual QString subkeyText( const GpgME::Subkey &, int ) const { return QString::null; } + virtual QString subkeyToolTip( const GpgME::Subkey & subkey, int column ) const; + virtual const QPixmap * subkeyPixmap( const GpgME::Subkey &, int ) const { return 0; } + virtual int subkeyCompare( const GpgME::Subkey & subkey1, const GpgME::Subkey & subkey2, const int column ) const; + + virtual QString userIDText( const GpgME::UserID &, int ) const { return QString::null; } + virtual QString userIDToolTip( const GpgME::UserID & userID, int column ) const; + virtual const QPixmap * userIDPixmap( const GpgME::UserID &, int ) const { return 0; } + virtual int userIDCompare( const GpgME::UserID & userID1, const GpgME::UserID & userID2, const int column ) const; + + virtual QString signatureText( const GpgME::UserID::Signature &, int ) const { return QString::null; } + virtual QString signatureToolTip( const GpgME::UserID::Signature & sig, int column ) const; + virtual const QPixmap * signaturePixmap( const GpgME::UserID::Signature &, int ) const { return 0; } + virtual int signatureCompare( const GpgME::UserID::Signature & sig1, const GpgME::UserID::Signature & sig2, const int column ) const; + }; + + class KDE_EXPORT DisplayStrategy { + public: + virtual ~DisplayStrategy(); + //font + virtual QFont keyFont( const GpgME::Key &, const QFont & ) const; + virtual QFont subkeyFont( const GpgME::Subkey &, const QFont & ) const; + virtual QFont useridFont( const GpgME::UserID &, const QFont & ) const; + virtual QFont signatureFont( const GpgME::UserID::Signature & , const QFont & ) const; + //foreground + virtual QColor keyForeground( const GpgME::Key & , const QColor & ) const; + virtual QColor subkeyForeground( const GpgME::Subkey &, const QColor & ) const; + virtual QColor useridForeground( const GpgME::UserID &, const QColor & ) const; + virtual QColor signatureForeground( const GpgME::UserID::Signature &, const QColor & ) const; + //background + virtual QColor keyBackground( const GpgME::Key &, const QColor & ) const; + virtual QColor subkeyBackground( const GpgME::Subkey &, const QColor & ) const; + virtual QColor useridBackground( const GpgME::UserID &, const QColor & ) const; + virtual QColor signatureBackground( const GpgME::UserID::Signature &, const QColor & ) const; + }; + + KeyListView( const ColumnStrategy * strategy, + const DisplayStrategy * display=0, + QWidget * parent=0, const char * name=0, WFlags f=0 ); + + ~KeyListView(); + + const ColumnStrategy * columnStrategy() const { return mColumnStrategy; } + const DisplayStrategy * displayStrategy() const { return mDisplayStrategy; } + + bool hierarchical() const { return mHierarchical; } + virtual void setHierarchical( bool hier ); + + void flushKeys() { slotUpdateTimeout(); } + + bool hasSelection() const; + + KeyListViewItem * itemByFingerprint( const QCString & ) const; + + signals: + void doubleClicked( Kleo::KeyListViewItem*, const QPoint&, int ); + void returnPressed( Kleo::KeyListViewItem* ); + void selectionChanged( Kleo::KeyListViewItem* ); + void contextMenu( Kleo::KeyListViewItem*, const QPoint& ); + + public slots: + virtual void slotAddKey( const GpgME::Key & key ); + virtual void slotRefreshKey( const GpgME::Key & key ); + + // + // Only boring stuff below: + // + private slots: + void slotEmitDoubleClicked( QListViewItem*, const QPoint&, int ); + void slotEmitReturnPressed( QListViewItem* ); + void slotEmitSelectionChanged( QListViewItem* ); + void slotEmitContextMenu( KListView*, QListViewItem*, const QPoint& ); + void slotUpdateTimeout(); + + public: + /*! \reimp for covariant return */ + KeyListViewItem * selectedItem() const; + /*! \reimp */ + QPtrList selectedItems() const; + /*! \reimp for covariant return */ + KeyListViewItem * firstChild() const; + /*! \reimp */ + void clear(); + /*! \reimp */ + void insertItem( QListViewItem * ); + /*! \reimp */ + void takeItem( QListViewItem * ); + + private: + void doHierarchicalInsert( const GpgME::Key & ); + void gatherScattered(); + void scatterGathered( QListViewItem * ); + void registerItem( KeyListViewItem * ); + void deregisterItem( const KeyListViewItem * ); + + private: + const ColumnStrategy * mColumnStrategy; + const DisplayStrategy * mDisplayStrategy; + bool mHierarchical; + + class Private; + Private * d; + }; +} + +#endif // __KLEO_KEYLISTVIEW_H__ diff --git a/lib/ui/keyrequester.cpp b/lib/ui/keyrequester.cpp index ff50bf271..d537affc5 100644 --- a/lib/ui/keyrequester.cpp +++ b/lib/ui/keyrequester.cpp @@ -1,481 +1,481 @@ /* -*- c++ -*- keyrequester.cpp This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004 Klar�vdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. Based on kpgpui.cpp Copyright (C) 2001,2002 the KPGP authors See file libkdenetwork/AUTHORS.kpgp for details This file is part of KPGP, the KDE PGP/GnuPG support library. KPGP is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifdef HAVE_CONFIG_H #include #endif #include "keyrequester.h" #include "keyselectiondialog.h" #include #include #include // gpgme++ #include #include // KDE #include #include #include #include #include #include // Qt #include #include #include #include #include #include #include #include Kleo::KeyRequester::KeyRequester( unsigned int allowedKeys, bool multipleKeys, QWidget * parent, const char * name ) : QWidget( parent, name ), mOpenPGPBackend( 0 ), mSMIMEBackend( 0 ), mMulti( multipleKeys ), mKeyUsage( allowedKeys ), mJobs( 0 ), d( 0 ) { init(); } Kleo::KeyRequester::KeyRequester( QWidget * parent, const char * name ) : QWidget( parent, name ), mOpenPGPBackend( 0 ), mSMIMEBackend( 0 ), mMulti( false ), mKeyUsage( 0 ), mJobs( 0 ), d( 0 ) { init(); } void Kleo::KeyRequester::init() { QHBoxLayout * hlay = new QHBoxLayout( this, 0, KDialog::spacingHint() ); // the label where the key id is to be displayed: mLabel = new QLabel( this ); mLabel->setFrameStyle( QFrame::Panel | QFrame::Sunken ); // the button to unset any key: mEraseButton = new KPushButton( this ); mEraseButton->setAutoDefault( false ); mEraseButton->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum ) ); mEraseButton->setIconSet( SmallIconSet( QApplication::reverseLayout() ? "locationbar_erase" : "clear_left" ) ); QToolTip::add( mEraseButton, i18n("Clear") ); // the button to call the KeySelectionDialog: mDialogButton = new QPushButton( i18n("Change..."), this ); mDialogButton->setAutoDefault( false ); hlay->addWidget( mLabel, 1 ); hlay->addWidget( mEraseButton ); hlay->addWidget( mDialogButton ); connect( mEraseButton, SIGNAL(clicked()), SLOT(slotEraseButtonClicked()) ); connect( mDialogButton, SIGNAL(clicked()), SLOT(slotDialogButtonClicked()) ); setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Fixed ) ); setAllowedKeys( mKeyUsage ); } Kleo::KeyRequester::~KeyRequester() { } const std::vector & Kleo::KeyRequester::keys() const { return mKeys; } const GpgME::Key & Kleo::KeyRequester::key() const { if ( mKeys.empty() ) return GpgME::Key::null; else return mKeys.front(); } void Kleo::KeyRequester::setKeys( const std::vector & keys ) { mKeys.clear(); for ( std::vector::const_iterator it = keys.begin() ; it != keys.end() ; ++it ) if ( !it->isNull() ) mKeys.push_back( *it ); updateKeys(); } void Kleo::KeyRequester::setKey( const GpgME::Key & key ) { mKeys.clear(); if ( !key.isNull() ) mKeys.push_back( key ); updateKeys(); } QString Kleo::KeyRequester::fingerprint() const { if ( mKeys.empty() ) return QString::null; else return mKeys.front().primaryFingerprint(); } QStringList Kleo::KeyRequester::fingerprints() const { QStringList result; for ( std::vector::const_iterator it = mKeys.begin() ; it != mKeys.end() ; ++it ) if ( !it->isNull() ) if ( const char * fpr = it->primaryFingerprint() ) result.push_back( fpr ); return result; } void Kleo::KeyRequester::setFingerprint( const QString & fingerprint ) { startKeyListJob( fingerprint ); } void Kleo::KeyRequester::setFingerprints( const QStringList & fingerprints ) { startKeyListJob( fingerprints ); } void Kleo::KeyRequester::updateKeys() { if ( mKeys.empty() ) { mLabel->clear(); return; } if ( mKeys.size() > 1 ) setMultipleKeysEnabled( true ); QStringList labelTexts; QString toolTipText; for ( std::vector::const_iterator it = mKeys.begin() ; it != mKeys.end() ; ++it ) { if ( it->isNull() ) continue; const QString fpr = it->primaryFingerprint(); labelTexts.push_back( fpr.right(8) ); toolTipText += fpr.right(8) + ": "; if ( const char * uid = it->userID(0).id() ) if ( it->protocol() == GpgME::Context::OpenPGP ) toolTipText += QString::fromUtf8( uid ); else toolTipText += Kleo::DN( uid ).prettyDN(); else toolTipText += i18n(""); toolTipText += '\n'; } mLabel->setText( labelTexts.join(", ") ); QToolTip::remove( mLabel ); QToolTip::add( mLabel, toolTipText ); } #ifndef __KLEO_UI_SHOW_KEY_LIST_ERROR_H__ #define __KLEO_UI_SHOW_KEY_LIST_ERROR_H__ static void showKeyListError( QWidget * parent, const GpgME::Error & err ) { assert( err ); const QString msg = i18n( "

An error occurred while fetching " "the keys from the backend:

" "

%1

" ) .arg( QString::fromLocal8Bit( err.asString() ) ); KMessageBox::error( parent, msg, i18n( "Key Listing Failed" ) ); } #endif // __KLEO_UI_SHOW_KEY_LIST_ERROR_H__ void Kleo::KeyRequester::startKeyListJob( const QStringList & fingerprints ) { if ( !mSMIMEBackend && !mOpenPGPBackend ) return; mTmpKeys.clear(); mJobs = 0; unsigned int count = 0; for ( QStringList::const_iterator it = fingerprints.begin() ; it != fingerprints.end() ; ++it ) if ( !(*it).stripWhiteSpace().isEmpty() ) ++count; if ( !count ) { // don't fall into the trap that an empty pattern means // "return all keys" :) setKey( GpgME::Key::null ); return; } if ( mOpenPGPBackend ) { KeyListJob * job = mOpenPGPBackend->keyListJob( false ); // local, no sigs if ( !job ) { KMessageBox::error( this, i18n("The OpenPGP backend does not support listing keys. " "Check your installation."), i18n("Key Listing Failed") ); } else { connect( job, SIGNAL(result(const GpgME::KeyListResult&)), SLOT(slotKeyListResult(const GpgME::KeyListResult&)) ); connect( job, SIGNAL(nextKey(const GpgME::Key&)), SLOT(slotNextKey(const GpgME::Key&)) ); const GpgME::Error err = job->start( fingerprints, mKeyUsage & Kleo::KeySelectionDialog::SecretKeys && !( mKeyUsage & Kleo::KeySelectionDialog::PublicKeys ) ); if ( err ) showKeyListError( this, err ); else ++mJobs; } } if ( mSMIMEBackend ) { KeyListJob * job = mSMIMEBackend->keyListJob( false ); // local, no sigs if ( !job ) { KMessageBox::error( this, i18n("The S/MIME backend does not support listing keys. " "Check your installation."), i18n("Key Listing Failed") ); } else { connect( job, SIGNAL(result(const GpgME::KeyListResult&)), SLOT(slotKeyListResult(const GpgME::KeyListResult&)) ); connect( job, SIGNAL(nextKey(const GpgME::Key&)), SLOT(slotNextKey(const GpgME::Key&)) ); const GpgME::Error err = job->start( fingerprints, mKeyUsage & Kleo::KeySelectionDialog::SecretKeys && !( mKeyUsage & Kleo::KeySelectionDialog::PublicKeys ) ); if ( err ) showKeyListError( this, err ); else ++mJobs; } } if ( mJobs > 0 ) { mEraseButton->setEnabled( false ); mDialogButton->setEnabled( false ); } } void Kleo::KeyRequester::slotNextKey( const GpgME::Key & key ) { if ( !key.isNull() ) mTmpKeys.push_back( key ); } void Kleo::KeyRequester::slotKeyListResult( const GpgME::KeyListResult & res ) { if ( res.error() ) showKeyListError( this, res.error() ); if ( --mJobs <= 0 ) { mEraseButton->setEnabled( true ); mDialogButton->setEnabled( true ); setKeys( mTmpKeys ); mTmpKeys.clear(); } } void Kleo::KeyRequester::slotDialogButtonClicked() { KeySelectionDialog * dlg = mKeys.empty() ? new KeySelectionDialog( mDialogCaption, mDialogMessage, mInitialQuery, mKeyUsage, mMulti, false, this ) : new KeySelectionDialog( mDialogCaption, mDialogCaption, mKeys, mKeyUsage, mMulti, false, this ) ; if ( dlg->exec() == QDialog::Accepted ) { if ( mMulti ) setKeys( dlg->selectedKeys() ); else setKey( dlg->selectedKey() ); emit changed(); } delete dlg; } void Kleo::KeyRequester::slotEraseButtonClicked() { if ( !mKeys.empty() ) emit changed(); mKeys.clear(); updateKeys(); } void Kleo::KeyRequester::setDialogCaption( const QString & caption ) { mDialogCaption = caption; } void Kleo::KeyRequester::setDialogMessage( const QString & msg ) { mDialogMessage = msg; } bool Kleo::KeyRequester::isMultipleKeysEnabled() const { return mMulti; } void Kleo::KeyRequester::setMultipleKeysEnabled( bool multi ) { if ( multi == mMulti ) return; if ( !multi && !mKeys.empty() ) mKeys.erase( mKeys.begin() + 1, mKeys.end() ); mMulti = multi; updateKeys(); } unsigned int Kleo::KeyRequester::allowedKeys() const { return mKeyUsage; } void Kleo::KeyRequester::setAllowedKeys( unsigned int keyUsage ) { mKeyUsage = keyUsage; mOpenPGPBackend = 0; mSMIMEBackend = 0; if ( mKeyUsage & KeySelectionDialog::OpenPGPKeys ) mOpenPGPBackend = Kleo::CryptoBackendFactory::instance()->openpgp(); if ( mKeyUsage & KeySelectionDialog::SMIMEKeys ) mSMIMEBackend = Kleo::CryptoBackendFactory::instance()->smime(); if ( mOpenPGPBackend && !mSMIMEBackend ) { mDialogCaption = i18n("OpenPGP Key Selection"); mDialogMessage = i18n("Please select an OpenPGP key to use."); } else if ( !mOpenPGPBackend && mSMIMEBackend ) { mDialogCaption = i18n("S/MIME Key Selection"); mDialogMessage = i18n("Please select an S/MIME key to use."); } else { mDialogCaption = i18n("Key Selection"); mDialogMessage = i18n("Please select an (OpenPGP or S/MIME) key to use."); } } QPushButton * Kleo::KeyRequester::dialogButton() { return mDialogButton; } QPushButton * Kleo::KeyRequester::eraseButton() { return mEraseButton; } static inline unsigned int foo( bool openpgp, bool smime, bool trusted, bool valid ) { unsigned int result = 0; if ( openpgp ) result |= Kleo::KeySelectionDialog::OpenPGPKeys; if ( smime ) result |= Kleo::KeySelectionDialog::SMIMEKeys; if ( trusted ) result |= Kleo::KeySelectionDialog::TrustedKeys; if ( valid ) result |= Kleo::KeySelectionDialog::ValidKeys; return result; } static inline unsigned int encryptionKeyUsage( bool openpgp, bool smime, bool trusted, bool valid ) { return foo( openpgp, smime, trusted, valid ) | Kleo::KeySelectionDialog::EncryptionKeys | Kleo::KeySelectionDialog::PublicKeys; } static inline unsigned int signingKeyUsage( bool openpgp, bool smime, bool trusted, bool valid ) { return foo( openpgp, smime, trusted, valid ) | Kleo::KeySelectionDialog::SigningKeys | Kleo::KeySelectionDialog::SecretKeys; } Kleo::EncryptionKeyRequester::EncryptionKeyRequester( bool multi, unsigned int proto, QWidget * parent, const char * name, bool onlyTrusted, bool onlyValid ) : KeyRequester( encryptionKeyUsage( proto & OpenPGP, proto & SMIME, onlyTrusted, onlyValid ), multi, parent, name ) { } Kleo::EncryptionKeyRequester::EncryptionKeyRequester( QWidget * parent, const char * name ) : KeyRequester( 0, false, parent, name ) { } Kleo::EncryptionKeyRequester::~EncryptionKeyRequester() {} void Kleo::EncryptionKeyRequester::setAllowedKeys( unsigned int proto, bool onlyTrusted, bool onlyValid ) { KeyRequester::setAllowedKeys( encryptionKeyUsage( proto & OpenPGP, proto & SMIME, onlyTrusted, onlyValid ) ); } Kleo::SigningKeyRequester::SigningKeyRequester( bool multi, unsigned int proto, QWidget * parent, const char * name, bool onlyTrusted, bool onlyValid ) : KeyRequester( signingKeyUsage( proto & OpenPGP, proto & SMIME, onlyTrusted, onlyValid ), multi, parent, name ) { } Kleo::SigningKeyRequester::SigningKeyRequester( QWidget * parent, const char * name ) : KeyRequester( 0, false, parent, name ) { } Kleo::SigningKeyRequester::~SigningKeyRequester() {} void Kleo::SigningKeyRequester::setAllowedKeys( unsigned int proto, bool onlyTrusted, bool onlyValid ) { KeyRequester::setAllowedKeys( signingKeyUsage( proto & OpenPGP, proto & SMIME, onlyTrusted, onlyValid ) ); } void Kleo::KeyRequester::virtual_hook( int, void* ) {} void Kleo::EncryptionKeyRequester::virtual_hook( int id, void * data ) { KeyRequester::virtual_hook( id, data ); } void Kleo::SigningKeyRequester::virtual_hook( int id, void * data ) { KeyRequester::virtual_hook( id, data ); } #include "keyrequester.moc" diff --git a/lib/ui/keyrequester.h b/lib/ui/keyrequester.h index e085a161a..3de9c508b 100644 --- a/lib/ui/keyrequester.h +++ b/lib/ui/keyrequester.h @@ -1,227 +1,227 @@ /* -*- c++ -*- keyrequester.h This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. Based on kpgpui.h Copyright (C) 2001,2002 the KPGP authors See file libkdenetwork/AUTHORS.kpgp for details This file is part of KPGP, the KDE PGP/GnuPG support library. KPGP is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __KLEO_UI_KEYREQUESTER_H__ #define __KLEO_UI_KEYREQUESTER_H__ #include #include #include #include namespace Kleo { class KeyListView; class KeyListViewItem; } namespace GpgME { class Key; class KeyListResult; } class QStringList; class QString; class QPushButton; class QLabel; namespace Kleo { /// Base class for SigningKeyRequester and EncryptionKeyRequester class KDE_EXPORT KeyRequester : public QWidget { Q_OBJECT public: KeyRequester( unsigned int allowedKeys, bool multipleKeys=false, QWidget * parent=0, const char * name=0 ); // Constructor for Qt Designer KeyRequester( QWidget * parent=0, const char * name=0 ); ~KeyRequester(); const GpgME::Key & key() const; /** Preferred method to set a key for non-multi-KeyRequesters. Doesn't start a backend KeyListJob. */ void setKey( const GpgME::Key & key ); const std::vector & keys() const; /** Preferred method to set a key for multi-KeyRequesters. Doesn't start a backend KeyListJob. */ void setKeys( const std::vector & keys ); QString fingerprint() const; /** Set the key by fingerprint. Starts a background KeyListJob to retrive the complete GpgME::Key object */ void setFingerprint( const QString & fingerprint ); QStringList fingerprints() const; /** Set the keys by fingerprint. Starts a background KeyListJob to retrive the complete GpgME::Key objects */ void setFingerprints( const QStringList & fingerprints ); QPushButton * eraseButton(); QPushButton * dialogButton(); void setDialogCaption( const QString & caption ); void setDialogMessage( const QString & message ); bool isMultipleKeysEnabled() const; void setMultipleKeysEnabled( bool enable ); unsigned int allowedKeys() const; void setAllowedKeys( unsigned int allowed ); void setInitialQuery( const QString & s ) { mInitialQuery = s; } const QString & initialQuery() const { return mInitialQuery; } signals: void changed(); private: void init(); void startKeyListJob( const QStringList & fingerprints ); void updateKeys(); private slots: void slotNextKey( const GpgME::Key & key ); void slotKeyListResult( const GpgME::KeyListResult & result ); void slotDialogButtonClicked(); void slotEraseButtonClicked(); private: const CryptoBackend::Protocol * mOpenPGPBackend; const CryptoBackend::Protocol * mSMIMEBackend; QLabel * mLabel; QPushButton * mEraseButton; QPushButton * mDialogButton; QString mDialogCaption, mDialogMessage, mInitialQuery; bool mMulti; unsigned int mKeyUsage; int mJobs; std::vector mKeys; std::vector mTmpKeys; private: class Private; Private * d; protected: virtual void virtual_hook( int, void* ); }; class KDE_EXPORT EncryptionKeyRequester : public KeyRequester { Q_OBJECT public: enum { OpenPGP = 1, SMIME = 2, AllProtocols = OpenPGP|SMIME }; /** * Preferred constructor */ EncryptionKeyRequester( bool multipleKeys=false, unsigned int proto=AllProtocols, QWidget * parent=0, const char * name=0, bool onlyTrusted=true, bool onlyValid=true ); /** * Constructor for Qt designer */ EncryptionKeyRequester( QWidget * parent=0, const char * name=0 ); ~EncryptionKeyRequester(); void setAllowedKeys( unsigned int proto, bool onlyTrusted=true, bool onlyValid=true ); private: class Private; Private * d; protected: virtual void virtual_hook( int, void* ); }; class KDE_EXPORT SigningKeyRequester : public KeyRequester { Q_OBJECT public: enum { OpenPGP = 1, SMIME = 2, AllProtocols = OpenPGP|SMIME }; /** * Preferred constructor * @param multipleKeys whether multiple keys can be selected * * @param proto the allowed protocols, OpenPGP and/or SMIME * @param onlyTrusted only show trusted keys * @param onlyValid only show valid keys */ SigningKeyRequester( bool multipleKeys=false, unsigned int proto=AllProtocols, QWidget * parent=0, const char * name=0, bool onlyTrusted=true, bool onlyValid=true ); /** * Constructor for Qt designer */ SigningKeyRequester( QWidget * parent=0, const char * name=0 ); ~SigningKeyRequester(); /* * Those parameters affect the parameters given to the key selection dialog. * @param proto the allowed protocols, OpenPGP and/or SMIME * @param onlyTrusted only show trusted keys * @param onlyValid only show valid keys */ void setAllowedKeys( unsigned int proto, bool onlyTrusted=true, bool onlyValid=true ); private: class Private; Private * d; protected: virtual void virtual_hook( int, void* ); }; } #endif // __KLEO_UI_KEYREQUESTER_H__ diff --git a/lib/ui/keyselectiondialog.cpp b/lib/ui/keyselectiondialog.cpp index 1f194a53c..b544711bb 100644 --- a/lib/ui/keyselectiondialog.cpp +++ b/lib/ui/keyselectiondialog.cpp @@ -1,779 +1,779 @@ /* -*- c++ -*- keyselectiondialog.cpp This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004 Klarälvdalens Datakonsult AB Based on kpgpui.cpp Copyright (C) 2001,2002 the KPGP authors See file libkdenetwork/AUTHORS.kpgp for details Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifdef HAVE_CONFIG_H #include #endif #include "keyselectiondialog.h" #include "keylistview.h" #include "progressdialog.h" #include #include #include // gpgme++ #include #include // KDE #include #include #include #include #include #include #include #include // Qt #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static bool checkKeyUsage( const GpgME::Key & key, unsigned int keyUsage ) { if ( keyUsage & Kleo::KeySelectionDialog::ValidKeys ) { if ( key.isInvalid() ) kdDebug() << "key is invalid - ignoring" << endl; if ( key.isExpired() ) { kdDebug() << "key is expired" << endl; return false; } else if ( key.isRevoked() ) { kdDebug() << "key is revoked" << endl; return false; } else if ( key.isDisabled() ) { kdDebug() << "key is disabled" << endl; return false; } } if ( keyUsage & Kleo::KeySelectionDialog::EncryptionKeys && !key.canEncrypt() ) { kdDebug() << "key can't encrypt" << endl; return false; } if ( keyUsage & Kleo::KeySelectionDialog::SigningKeys && !key.canSign() ) { kdDebug() << "key can't sign" << endl; return false; } if ( keyUsage & Kleo::KeySelectionDialog::CertificationKeys && !key.canCertify() ) { kdDebug() << "key can't certify" << endl; return false; } if ( keyUsage & Kleo::KeySelectionDialog::AuthenticationKeys && !key.canAuthenticate() ) { kdDebug() << "key can't authenticate" << endl; return false; } if ( keyUsage & Kleo::KeySelectionDialog::SecretKeys && !( keyUsage & Kleo::KeySelectionDialog::PublicKeys ) && !key.isSecret() ) { kdDebug() << "key isn't secret" << endl; return false; } if ( keyUsage & Kleo::KeySelectionDialog::TrustedKeys && key.protocol() == GpgME::Context::OpenPGP && // only check this for secret keys for now. // Seems validity isn't checked for secret keylistings... !key.isSecret() ) { std::vector uids = key.userIDs(); for ( std::vector::const_iterator it = uids.begin() ; it != uids.end() ; ++it ) if ( !it->isRevoked() && it->validity() >= GpgME::UserID::Marginal ) return true; kdDebug() << "key has no UIDs with validity >= Marginal" << endl; return false; } // X.509 keys are always trusted, else they won't be the keybox. // PENDING(marc) check that this ^ is correct return true; } static bool checkKeyUsage( const std::vector & keys, unsigned int keyUsage ) { for ( std::vector::const_iterator it = keys.begin() ; it != keys.end() ; ++it ) if ( !checkKeyUsage( *it, keyUsage ) ) return false; return true; } static inline QString time_t2string( time_t t ) { QDateTime dt; dt.setTime_t( t ); return dt.toString(); } namespace { class ColumnStrategy : public Kleo::KeyListView::ColumnStrategy { public: ColumnStrategy( unsigned int keyUsage ); QString title( int col ) const; int width( int col, const QFontMetrics & fm ) const; QString text( const GpgME::Key & key, int col ) const; QString toolTip( const GpgME::Key & key, int col ) const; const QPixmap * pixmap( const GpgME::Key & key, int col ) const; private: const QPixmap mKeyGoodPix, mKeyBadPix, mKeyUnknownPix, mKeyValidPix; const unsigned int mKeyUsage; }; ColumnStrategy::ColumnStrategy( unsigned int keyUsage ) : Kleo::KeyListView::ColumnStrategy(), mKeyGoodPix( UserIcon( "key_ok" ) ), mKeyBadPix( UserIcon( "key_bad" ) ), mKeyUnknownPix( UserIcon( "key_unknown" ) ), mKeyValidPix( UserIcon( "key" ) ), mKeyUsage( keyUsage ) { kdWarning( keyUsage == 0, 5150 ) << "KeySelectionDialog: keyUsage == 0. You want to use AllKeys instead." << endl; } QString ColumnStrategy::title( int col ) const { switch ( col ) { case 0: return i18n("Key ID"); case 1: return i18n("User ID"); default: return QString::null; } } int ColumnStrategy::width( int col, const QFontMetrics & fm ) const { if ( col == 0 ) { static const char hexchars[] = "0123456789ABCDEF"; int maxWidth = 0; for ( unsigned int i = 0 ; i < 16 ; ++i ) maxWidth = kMax( fm.width( QChar( hexchars[i] ) ), maxWidth ); return 8 * maxWidth + 2 * mKeyGoodPix.width(); } return Kleo::KeyListView::ColumnStrategy::width( col, fm ); } QString ColumnStrategy::text( const GpgME::Key & key, int col ) const { switch ( col ) { case 0: { if ( key.shortKeyID() ) return QString::fromUtf8( key.shortKeyID() ); else return i18n(""); } break; case 1: { const char * uid = key.userID(0).id(); if ( key.protocol() == GpgME::Context::OpenPGP ) return uid && *uid ? QString::fromUtf8( uid ) : QString::null ; else // CMS return Kleo::DN( uid ).prettyDN(); } break; default: return QString::null; } } QString ColumnStrategy::toolTip( const GpgME::Key & key, int ) const { const char * uid = key.userID(0).id(); const char * fpr = key.primaryFingerprint(); const char * issuer = key.issuerName(); const GpgME::Subkey subkey = key.subkey(0); const QString expiry = subkey.neverExpires() ? i18n("never") : time_t2string( subkey.expirationTime() ) ; const QString creation = time_t2string( subkey.creationTime() ); if ( key.protocol() == GpgME::Context::OpenPGP ) return i18n( "OpenPGP key for %1\n" "Created: %2\n" "Expiry: %3\n" "Fingerprint: %4" ) .arg( uid ? QString::fromUtf8( uid ) : i18n("unknown"), creation, expiry, fpr ? QString::fromLatin1( fpr ) : i18n("unknown") ); else return i18n( "S/MIME key for %1\n" "Created: %2\n" "Expiry: %3\n" "Fingerprint: %4\n" "Issuer: %5" ) .arg( uid ? Kleo::DN( uid ).prettyDN() : i18n("unknown"), creation, expiry, fpr ? QString::fromLatin1( fpr ) : i18n("unknown") ) .arg( issuer ? Kleo::DN( issuer ).prettyDN() : i18n("unknown") ); } const QPixmap * ColumnStrategy::pixmap( const GpgME::Key & key, int col ) const { if ( col != 0 ) return 0; // this key did not undergo a validating keylisting yet: if ( !( key.keyListMode() & GpgME::Context::Validate ) ) return &mKeyUnknownPix; if ( !checkKeyUsage( key, mKeyUsage ) ) return &mKeyBadPix; 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; } } } static const int sCheckSelectionDelay = 250; Kleo::KeySelectionDialog::KeySelectionDialog( const QString & title, const QString & text, const std::vector & selectedKeys, unsigned int keyUsage, bool extendedSelection, bool rememberChoice, QWidget * parent, const char * name, bool modal ) : KDialogBase( parent, name, modal, title, Default|Ok|Cancel, Ok ), mOpenPGPBackend( 0 ), mSMIMEBackend( 0 ), mRememberCB( 0 ), mSelectedKeys( selectedKeys ), mKeyUsage( keyUsage ), mCurrentContextMenuItem( 0 ) { init( rememberChoice, extendedSelection, text, QString::null ); } Kleo::KeySelectionDialog::KeySelectionDialog( const QString & title, const QString & text, const QString & initialQuery, unsigned int keyUsage, bool extendedSelection, bool rememberChoice, QWidget * parent, const char * name, bool modal ) : KDialogBase( parent, name, modal, title, Default|Ok|Cancel, Ok ), mOpenPGPBackend( 0 ), mSMIMEBackend( 0 ), mRememberCB( 0 ), mKeyUsage( keyUsage ), mSearchText( initialQuery ), mCurrentContextMenuItem( 0 ) { init( rememberChoice, extendedSelection, text, initialQuery ); } void Kleo::KeySelectionDialog::init( bool rememberChoice, bool extendedSelection, const QString & text, const QString & initialQuery ) { if ( mKeyUsage & OpenPGPKeys ) mOpenPGPBackend = Kleo::CryptoBackendFactory::instance()->openpgp(); if ( mKeyUsage & SMIMEKeys ) mSMIMEBackend = Kleo::CryptoBackendFactory::instance()->smime(); QSize dialogSize( 580, 400 ); if ( kapp ) { KWin::setIcons( winId(), kapp->icon(), kapp->miniIcon() ); KConfigGroup dialogConfig( KGlobal::config(), "Key Selection Dialog" ); dialogSize = dialogConfig.readSizeEntry( "Dialog size", &dialogSize ); } resize( dialogSize ); mCheckSelectionTimer = new QTimer( this ); mStartSearchTimer = new QTimer( this ); QFrame *page = makeMainWidget(); QVBoxLayout *topLayout = new QVBoxLayout( page, 0, spacingHint() ); if ( !text.isEmpty() ) topLayout->addWidget( new QLabel( text, page ) ); QHBoxLayout * hlay = new QHBoxLayout( topLayout ); // inherits spacing QLineEdit * le = new QLineEdit( page ); le->setText( initialQuery ); QToolButton *clearButton = new QToolButton( page ); clearButton->setIconSet( KGlobal::iconLoader()->loadIconSet( KApplication::reverseLayout() ? "clear_left":"locationbar_erase", KIcon::Small, 0 ) ); hlay->addWidget( clearButton ); hlay->addWidget( new QLabel( le, i18n("&Search for:"), page ) ); hlay->addWidget( le, 1 ); le->setFocus(); connect( clearButton, SIGNAL( clicked() ), le, SLOT( clear() ) ); connect( le, SIGNAL(textChanged(const QString&)), this, SLOT(slotSearch(const QString&)) ); connect( mStartSearchTimer, SIGNAL(timeout()), SLOT(slotFilter()) ); mKeyListView = new KeyListView( new ColumnStrategy( mKeyUsage ), 0, page, "mKeyListView" ); mKeyListView->setResizeMode( QListView::LastColumn ); mKeyListView->setRootIsDecorated( true ); mKeyListView->setShowSortIndicator( true ); mKeyListView->setSorting( 1, true ); // sort by User ID mKeyListView->setShowToolTips( true ); if ( extendedSelection ) mKeyListView->setSelectionMode( QListView::Extended ); topLayout->addWidget( mKeyListView, 10 ); if ( rememberChoice ) { mRememberCB = new QCheckBox( i18n("&Remember choice"), page ); topLayout->addWidget( mRememberCB ); QWhatsThis::add( mRememberCB, i18n("

If you check this box your choice will " "be stored and you will not be asked again." "

") ); } connect( mCheckSelectionTimer, SIGNAL(timeout()), SLOT(slotCheckSelection()) ); connectSignals(); connect( mKeyListView, SIGNAL(doubleClicked(Kleo::KeyListViewItem*,const QPoint&,int)), SLOT(slotTryOk()) ); connect( mKeyListView, SIGNAL(contextMenu(Kleo::KeyListViewItem*,const QPoint&)), SLOT(slotRMB(Kleo::KeyListViewItem*,const QPoint&)) ); setButtonText( KDialogBase::Default, i18n("&Reread Keys") ); connect( this, SIGNAL(defaultClicked()), this, SLOT(slotRereadKeys()) ); slotRereadKeys(); } Kleo::KeySelectionDialog::~KeySelectionDialog() { KConfigGroup dialogConfig( KGlobal::config(), "Key Selection Dialog" ); dialogConfig.writeEntry( "Dialog size", size() ); dialogConfig.sync(); } void Kleo::KeySelectionDialog::connectSignals() { if ( mKeyListView->isMultiSelection() ) connect( mKeyListView, SIGNAL(selectionChanged()), SLOT(slotSelectionChanged()) ); else connect( mKeyListView, SIGNAL(selectionChanged(Kleo::KeyListViewItem*)), SLOT(slotCheckSelection(Kleo::KeyListViewItem*)) ); } void Kleo::KeySelectionDialog::disconnectSignals() { if ( mKeyListView->isMultiSelection() ) disconnect( mKeyListView, SIGNAL(selectionChanged()), this, SLOT(slotSelectionChanged()) ); else disconnect( mKeyListView, SIGNAL(selectionChanged(Kleo::KeyListViewItem*)), this, SLOT(slotCheckSelection(Kleo::KeyListViewItem*)) ); } const GpgME::Key & Kleo::KeySelectionDialog::selectedKey() const { if ( mKeyListView->isMultiSelection() || !mKeyListView->selectedItem() ) return GpgME::Key::null; return mKeyListView->selectedItem()->key(); } QString Kleo::KeySelectionDialog::fingerprint() const { return selectedKey().primaryFingerprint(); } QStringList Kleo::KeySelectionDialog::fingerprints() const { QStringList result; for ( std::vector::const_iterator it = mSelectedKeys.begin() ; it != mSelectedKeys.end() ; ++it ) if ( const char * fpr = it->primaryFingerprint() ) result.push_back( fpr ); return result; } QStringList Kleo::KeySelectionDialog::pgpKeyFingerprints() const { QStringList result; for ( std::vector::const_iterator it = mSelectedKeys.begin() ; it != mSelectedKeys.end() ; ++it ) if ( it->protocol() == GpgME::Context::OpenPGP ) if ( const char * fpr = it->primaryFingerprint() ) result.push_back( fpr ); return result; } QStringList Kleo::KeySelectionDialog::smimeFingerprints() const { QStringList result; for ( std::vector::const_iterator it = mSelectedKeys.begin() ; it != mSelectedKeys.end() ; ++it ) if ( it->protocol() == GpgME::Context::CMS ) if ( const char * fpr = it->primaryFingerprint() ) result.push_back( fpr ); return result; } void Kleo::KeySelectionDialog::slotRereadKeys() { mKeyListView->clear(); mListJobCount = 0; mTruncated = 0; mSavedOffsetY = mKeyListView->contentsY(); disconnectSignals(); mKeyListView->setEnabled( false ); // FIXME: save current selection if ( mOpenPGPBackend ) startKeyListJobForBackend( mOpenPGPBackend, std::vector(), false /*non-validating*/ ); if ( mSMIMEBackend ) startKeyListJobForBackend( mSMIMEBackend, std::vector(), false /*non-validating*/ ); if ( mListJobCount == 0 ) { mKeyListView->setEnabled( true ); KMessageBox::information( this, i18n("No backends found for listing keys. " "Check your installation."), i18n("Key Listing Failed") ); connectSignals(); } } #ifndef __KLEO_UI_SHOW_KEY_LIST_ERROR_H__ #define __KLEO_UI_SHOW_KEY_LIST_ERROR_H__ static void showKeyListError( QWidget * parent, const GpgME::Error & err ) { assert( err ); const QString msg = i18n( "

An error occurred while fetching " "the keys from the backend:

" "

%1

" ) .arg( QString::fromLocal8Bit( err.asString() ) ); KMessageBox::error( parent, msg, i18n( "Key Listing Failed" ) ); } #endif // __KLEO_UI_SHOW_KEY_LIST_ERROR_H__ namespace { struct ExtractFingerprint { QString operator()( const GpgME::Key & key ) { return key.primaryFingerprint(); } }; } void Kleo::KeySelectionDialog::startKeyListJobForBackend( const CryptoBackend::Protocol * backend, const std::vector & keys, bool validate ) { assert( backend ); KeyListJob * job = backend->keyListJob( false, false, validate ); // local, w/o sigs, validation as givem if ( !job ) return; connect( job, SIGNAL(result(const GpgME::KeyListResult&)), SLOT(slotKeyListResult(const GpgME::KeyListResult&)) ); connect( job, SIGNAL(nextKey(const GpgME::Key&)), mKeyListView, validate ? SLOT(slotRefreshKey(const GpgME::Key&)) : SLOT(slotAddKey(const GpgME::Key&)) ); QStringList fprs; std::transform( keys.begin(), keys.end(), std::back_inserter( fprs ), ExtractFingerprint() ); const GpgME::Error err = job->start( fprs, mKeyUsage & SecretKeys && !( mKeyUsage & PublicKeys ) ); if ( err ) return showKeyListError( this, err ); // FIXME: create a MultiProgressDialog: (void)new ProgressDialog( job, validate ? i18n( "Checking selected keys..." ) : i18n( "Fetching keys..." ), this ); ++mListJobCount; } static void selectKeys( Kleo::KeyListView * klv, const std::vector & selectedKeys ) { klv->clearSelection(); if ( selectedKeys.empty() ) return; for ( std::vector::const_iterator it = selectedKeys.begin() ; it != selectedKeys.end() ; ++it ) if ( Kleo::KeyListViewItem * item = klv->itemByFingerprint( it->primaryFingerprint() ) ) item->setSelected( true ); } void Kleo::KeySelectionDialog::slotKeyListResult( const GpgME::KeyListResult & res ) { if ( res.error() ) showKeyListError( this, res.error() ); else if ( res.isTruncated() ) ++mTruncated; if ( --mListJobCount > 0 ) return; // not yet finished... if ( mTruncated > 0 ) KMessageBox::information( this, i18n("One backend returned truncated output.
" "Not all available keys are shown
", "%n backends returned truncated output.
" "Not all available keys are shown
", mTruncated), i18n("Key List Result") ); mKeyListView->flushKeys(); mKeyListView->setEnabled( true ); mListJobCount = mTruncated = 0; mKeysToCheck.clear(); selectKeys( mKeyListView, mSelectedKeys ); slotFilter(); connectSignals(); slotSelectionChanged(); // restore the saved position of the contents mKeyListView->setContentsPos( 0, mSavedOffsetY ); mSavedOffsetY = 0; } void Kleo::KeySelectionDialog::slotSelectionChanged() { kdDebug(5150) << "KeySelectionDialog::slotSelectionChanged()" << endl; // (re)start the check selection timer. Checking the selection is delayed // because else drag-selection doesn't work very good (checking key trust // is slow). mCheckSelectionTimer->start( sCheckSelectionDelay ); } namespace { struct AlreadyChecked { bool operator()( const GpgME::Key & key ) const { return key.keyListMode() & GpgME::Context::Validate ; } }; } void Kleo::KeySelectionDialog::slotCheckSelection( KeyListViewItem * item ) { kdDebug(5150) << "KeySelectionDialog::slotCheckSelection()\n"; mCheckSelectionTimer->stop(); mSelectedKeys.clear(); if ( !mKeyListView->isMultiSelection() ) { if ( item ) mSelectedKeys.push_back( item->key() ); } 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(), std::back_inserter( mKeysToCheck ), AlreadyChecked() ); if ( mKeysToCheck.empty() ) { enableButtonOK( !mSelectedKeys.empty() && checkKeyUsage( mSelectedKeys, mKeyUsage ) ); return; } // performed all fast checks - now for validating key listing: startValidatingKeyListing(); } void Kleo::KeySelectionDialog::startValidatingKeyListing() { if ( mKeysToCheck.empty() ) return; mListJobCount = 0; mTruncated = 0; mSavedOffsetY = mKeyListView->contentsY(); disconnectSignals(); mKeyListView->setEnabled( false ); std::vector smime, openpgp; for ( std::vector::const_iterator it = mKeysToCheck.begin() ; it != mKeysToCheck.end() ; ++it ) if ( it->protocol() == GpgME::Context::OpenPGP ) openpgp.push_back( *it ); else smime.push_back( *it ); if ( !openpgp.empty() ) { assert( mOpenPGPBackend ); startKeyListJobForBackend( mOpenPGPBackend, openpgp, true /*validate*/ ); } if ( !smime.empty() ) { assert( mSMIMEBackend ); startKeyListJobForBackend( mSMIMEBackend, smime, true /*validate*/ ); } assert( mListJobCount > 0 ); } bool Kleo::KeySelectionDialog::rememberSelection() const { return mRememberCB && mRememberCB->isChecked() ; } void Kleo::KeySelectionDialog::slotRMB( Kleo::KeyListViewItem * item, const QPoint & p ) { if ( !item ) return; mCurrentContextMenuItem = item; QPopupMenu menu; menu.insertItem( i18n( "Recheck Key" ), this, SLOT(slotRecheckKey()) ); menu.exec( p ); } void Kleo::KeySelectionDialog::slotRecheckKey() { if ( !mCurrentContextMenuItem || mCurrentContextMenuItem->key().isNull() ) return; mKeysToCheck.clear(); mKeysToCheck.push_back( mCurrentContextMenuItem->key() ); } void Kleo::KeySelectionDialog::slotTryOk() { if ( actionButton( Ok )->isEnabled() ) slotOk(); } void Kleo::KeySelectionDialog::slotOk() { if ( mCheckSelectionTimer->isActive() ) slotCheckSelection(); mStartSearchTimer->stop(); accept(); } void Kleo::KeySelectionDialog::slotCancel() { mCheckSelectionTimer->stop(); mStartSearchTimer->stop(); reject(); } void Kleo::KeySelectionDialog::slotSearch( const QString & text ) { mSearchText = text.stripWhiteSpace().upper(); slotSearch(); } void Kleo::KeySelectionDialog::slotSearch() { mStartSearchTimer->start( sCheckSelectionDelay, true /*single-shot*/ ); } void Kleo::KeySelectionDialog::slotFilter() { if ( mSearchText.isEmpty() ) { showAllItems(); return; } // OK, so we need to filter: QRegExp keyIdRegExp( "(?:0x)?[A-F0-9]{1,8}", false /*case-insens.*/ ); if ( keyIdRegExp.exactMatch( mSearchText ) ) { if ( mSearchText.startsWith( "0X" ) ) // search for keyID only: filterByKeyID( mSearchText.mid( 2 ) ); else // search for UID and keyID: filterByKeyIDOrUID( mSearchText ); } else { // search in UID: filterByUID( mSearchText ); } } void Kleo::KeySelectionDialog::filterByKeyID( const QString & keyID ) { assert( keyID.length() <= 8 ); assert( !keyID.isEmpty() ); // regexp in slotFilter should prevent these if ( keyID.isEmpty() ) showAllItems(); else for ( KeyListViewItem * item = mKeyListView->firstChild() ; item ; item = item->nextSibling() ) item->setVisible( item->text( 0 ).upper().startsWith( keyID ) ); } static bool anyUIDMatches( const Kleo::KeyListViewItem * item, QRegExp & rx ) { if ( !item ) return false; const std::vector uids = item->key().userIDs(); for ( std::vector::const_iterator it = uids.begin() ; it != uids.end() ; ++it ) if ( it->id() && rx.search( QString::fromUtf8( it->id() ) ) >= 0 ) return true; return false; } void Kleo::KeySelectionDialog::filterByKeyIDOrUID( const QString & str ) { assert( !str.isEmpty() ); // match beginnings of words: QRegExp rx( "\\b" + QRegExp::escape( str ), false ); for ( KeyListViewItem * item = mKeyListView->firstChild() ; item ; item = item->nextSibling() ) item->setVisible( item->text( 0 ).upper().startsWith( str ) || anyUIDMatches( item, rx ) ); } void Kleo::KeySelectionDialog::filterByUID( const QString & str ) { assert( !str.isEmpty() ); // match beginnings of words: QRegExp rx( "\\b" + QRegExp::escape( str ), false ); for ( KeyListViewItem * item = mKeyListView->firstChild() ; item ; item = item->nextSibling() ) item->setVisible( anyUIDMatches( item, rx ) ); } void Kleo::KeySelectionDialog::showAllItems() { for ( KeyListViewItem * item = mKeyListView->firstChild() ; item ; item = item->nextSibling() ) item->setVisible( true ); } #include "keyselectiondialog.moc" diff --git a/lib/ui/keyselectiondialog.h b/lib/ui/keyselectiondialog.h new file mode 100644 index 000000000..0f7607ebc --- /dev/null +++ b/lib/ui/keyselectiondialog.h @@ -0,0 +1,168 @@ +/* -*- c++ -*- + keyselectiondialog.h + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Based on kpgpui.h + Copyright (C) 2001,2002 the KPGP authors + See file libkdenetwork/AUTHORS.kpgp for details + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifndef __KLEO_UI_KEYSELECTIONDIALOG_H__ +#define __KLEO_UI_KEYSELECTIONDIALOG_H__ + +#include + +#include +#include +#include +#include + +class QCheckBox; +class QPixmap; +class QTimer; +class QListViewItem; +class QRegExp; +class QPoint; + +namespace Kleo { + class KeyListView; + class KeyListViewItem; +} + +namespace GpgME { + class KeyListResult; +} + +namespace Kleo { + + class KDE_EXPORT KeySelectionDialog : public KDialogBase { + Q_OBJECT + public: + + enum KeyUsage { + PublicKeys = 1, + SecretKeys = 2, + EncryptionKeys = 4, + SigningKeys = 8, + ValidKeys = 16, + TrustedKeys = 32, + CertificationKeys = 64, + AuthenticationKeys = 128, + OpenPGPKeys = 256, + SMIMEKeys = 512, + AllKeys = PublicKeys | SecretKeys | OpenPGPKeys | SMIMEKeys, + ValidTrustedEncryptionKeys = AllKeys | EncryptionKeys | ValidKeys | TrustedKeys + }; + + KeySelectionDialog( const QString & title, + const QString & text, + const std::vector & selectedKeys=std::vector(), + unsigned int keyUsage=AllKeys, + bool extendedSelection=false, + bool rememberChoice=false, + QWidget * parent=0, const char * name=0, + bool modal=true ); + KeySelectionDialog( const QString & title, + const QString & text, + const QString & initialPattern, + unsigned int keyUsage=AllKeys, + bool extendedSelection=false, + bool rememberChoice=false, + QWidget * parent=0, const char * name=0, + bool modal=true ); + ~KeySelectionDialog(); + + /** Returns the key ID of the selected key in single selection mode. + Otherwise it returns a null key. */ + const GpgME::Key & selectedKey() const; + + QString fingerprint() const; + + /** Returns a list of selected key IDs. */ + const std::vector & selectedKeys() const { return mSelectedKeys; } + + /// Return all the selected fingerprints + QStringList fingerprints() const; + + /// Return the selected openpgp fingerprints + QStringList pgpKeyFingerprints() const; + /// Return the selected smime fingerprints + QStringList smimeFingerprints() const; + + bool rememberSelection() const; + + private slots: + void slotRereadKeys(); + void slotKeyListResult( const GpgME::KeyListResult & ); + void slotSelectionChanged(); + void slotCheckSelection() { slotCheckSelection( 0 ); } + void slotCheckSelection( Kleo::KeyListViewItem * ); + void slotRMB( Kleo::KeyListViewItem *, const QPoint & ); + void slotRecheckKey(); + void slotTryOk(); + void slotOk(); + void slotCancel(); + void slotSearch( const QString & text ); + void slotSearch(); + void slotFilter(); + + private: + void filterByKeyID( const QString & keyID ); + void filterByKeyIDOrUID( const QString & keyID ); + void filterByUID( const QString & uid ); + void showAllItems(); + bool anyChildMatches( const Kleo::KeyListViewItem * item, QRegExp & rx ) const; + + void connectSignals(); + void disconnectSignals(); + + void startKeyListJobForBackend( const Kleo::CryptoBackend::Protocol *, const std::vector &, bool ); + void startValidatingKeyListing(); + + void init( bool, bool, const QString &, const QString & ); + + private: + Kleo::KeyListView * mKeyListView; + const Kleo::CryptoBackend::Protocol * mOpenPGPBackend; + const Kleo::CryptoBackend::Protocol * mSMIMEBackend; + QCheckBox * mRememberCB; + std::vector mSelectedKeys, mKeysToCheck; + unsigned int mKeyUsage; + QTimer * mCheckSelectionTimer; + QTimer * mStartSearchTimer; + // cross-eventloop temporaries: + QString mSearchText; + Kleo::KeyListViewItem * mCurrentContextMenuItem; + int mTruncated, mListJobCount, mSavedOffsetY; + }; + +} + +#endif // __KLEO_UI_KEYSELECTIONDIALOG_H__ diff --git a/lib/ui/passphrasedialog.cpp b/lib/ui/passphrasedialog.cpp index 986de9842..5915387f5 100644 --- a/lib/ui/passphrasedialog.cpp +++ b/lib/ui/passphrasedialog.cpp @@ -1,123 +1,123 @@ /* -*- c++ -*- passphrasedialog.cpp This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. Based on kpgpui.cpp Copyright (C) 2001,2002 the KPGP authors See file libkdenetwork/AUTHORS.kpgp for details This file is part of KPGP, the KDE PGP/GnuPG support library. KPGP is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef HAVE_CONFIG_H #include #endif #include "passphrasedialog.h" #include #include #include #include #include #include struct Kleo::PassphraseDialog::Private { KPasswordEdit * lineedit; }; Kleo::PassphraseDialog::PassphraseDialog( const QString & msg, const QString & caption, QWidget * parent, const char * name, bool modal ) : KDialogBase( parent, name, modal, caption, Ok|Cancel, Ok ), d( 0 ) { d = new Private(); QWidget * w = new QWidget( this ); setMainWidget( w ); QHBoxLayout * hlay = new QHBoxLayout( w, 0, spacingHint() ); QLabel * label = new QLabel( w ); label->setPixmap( DesktopIcon( "pgp-keys", KIcon::SizeMedium ) ); hlay->addWidget( label, 0, AlignTop ); QVBoxLayout * vlay = new QVBoxLayout( hlay ); // inherits spacing vlay->addWidget( new QLabel( msg.isEmpty() ? i18n("Please enter your passphrase:") : msg, w ) ); d->lineedit = new KPasswordEdit( KPasswordEdit::OneStar, w, "d->lineedit" ); d->lineedit->setMinimumWidth( fontMetrics().width("*") * 20 ); d->lineedit->setFocus(); vlay->addWidget( d->lineedit ); connect( d->lineedit, SIGNAL(returnPressed()), SLOT(slotOk()) ); disableResize(); } Kleo::PassphraseDialog::~PassphraseDialog() { delete d; d = 0; } const char * Kleo::PassphraseDialog::passphrase() const { return d->lineedit->password(); } void Kleo::PassphraseDialog::slotOk() { const char * pass = passphrase(); emit finished( pass ? pass : "" ); KDialogBase::slotOk(); } void Kleo::PassphraseDialog::slotCancel() { emit canceled(); KDialogBase::slotCancel(); } void Kleo::PassphraseDialog::virtual_hook( int id, void * data ) { return KDialogBase::virtual_hook( id, data ); } #include "passphrasedialog.moc" diff --git a/lib/ui/passphrasedialog.h b/lib/ui/passphrasedialog.h index b53619509..12a434e13 100644 --- a/lib/ui/passphrasedialog.h +++ b/lib/ui/passphrasedialog.h @@ -1,91 +1,91 @@ /* -*- c++ -*- passphrasedialog.h This file is part of libkleopatra, the KDE keymanagement library Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. Based on kpgpui.h Copyright (C) 2001,2002 the KPGP authors See file libkdenetwork/AUTHORS.kpgp for details This file is part of KPGP, the KDE PGP/GnuPG support library. KPGP is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __KLEO_UI_PASSPHRASEDIALOG_H__ #define __KLEO_UI_PASSPHRASEDIALOG_H__ #include namespace Kleo { class PassphraseDialog : public KDialogBase { Q_OBJECT public: PassphraseDialog( const QString & description, const QString & caption=QString::null, QWidget * parent=0, const char * name=0, bool modal=true ); ~PassphraseDialog(); const char * passphrase() const; signals: /** emitted when the user clicks Ok. \a pass is never NULL. \c pass only valid inside slots connected to this signal. */ void finished( const char * pass ); /** emitted when the user clicks Cancel. */ void canceled(); protected slots: /*! \reimp */ void slotOk(); /*! \reimp */ void slotCancel(); private: class Private; Private * d; protected: /*! \reimp */ void virtual_hook( int, void* ); }; } // namespace Kleo #endif // __KLEO_UI_PASSPHRASEDIALOG_H__ diff --git a/lib/ui/progressbar.cpp b/lib/ui/progressbar.cpp new file mode 100644 index 000000000..96f51fa8a --- /dev/null +++ b/lib/ui/progressbar.cpp @@ -0,0 +1,111 @@ +/* + progressbar.cpp + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#include "config.h" +#include "progressbar.h" + +#include +#include + +static const int busyTimerTickInterval = 100; +static const int busyTimerTickIncrement = 5; + +Kleo::ProgressBar::ProgressBar( QWidget * parent, const char * name, WFlags f ) + : QProgressBar( 0, parent, name, f ), + mRealProgress( -1 ) +{ + mBusyTimer = new QTimer( this ); + connect( mBusyTimer, SIGNAL(timeout()), SLOT(slotBusyTimerTick()) ); + fixup( true ); +} + +void Kleo::ProgressBar::slotProgress( const QString &, int cur, int tot ) { + setProgress( cur, tot ); +} + +void Kleo::ProgressBar::slotProgress( const QString &, int, int cur, int tot ) { + setProgress( cur, tot ); +} + +void Kleo::ProgressBar::setTotalSteps( int total ) { + kdDebug() << "Kleo::ProgressBar::setTotalSteps( " << total << " )" << endl; + if ( total == totalSteps() ) + return; + QProgressBar::setTotalSteps( 0 ); + fixup( false ); +} + +void Kleo::ProgressBar::setProgress( int p ) { + kdDebug() << "Kleo::ProgressBar::setProgress( " << p << " )" << endl; + mRealProgress = p; + fixup( true ); +} + +void Kleo::ProgressBar::reset() { + mRealProgress = -1; + fixup( true ); +} + +void Kleo::ProgressBar::slotBusyTimerTick() { + fixup( false ); + if ( mBusyTimer->isActive() ) + QProgressBar::setProgress( QProgressBar::progress() + busyTimerTickIncrement ); +} + +void Kleo::ProgressBar::fixup( bool newValue ) { + const int cur = QProgressBar::progress(); + const int tot = QProgressBar::totalSteps(); + + kdDebug() << "Kleo::ProgressBar::startStopBusyTimer() cur = " << cur << "; tot = " << tot << "; real = " << mRealProgress << endl; + + if ( ( newValue && mRealProgress < 0 ) || ( !newValue && cur < 0 ) ) { + kdDebug() << "(new value) switch to reset" << endl; + mBusyTimer->stop(); + if ( newValue ) + QProgressBar::reset(); + mRealProgress = -1; + } else if ( tot == 0 ) { + kdDebug() << "(new value) switch or stay in busy" << endl; + if ( !mBusyTimer->isActive() ) { + mBusyTimer->start( busyTimerTickInterval ); + if ( newValue ) + QProgressBar::setProgress( mRealProgress ); + } + } else { + kdDebug() << "(new value) normal progress" << endl; + mBusyTimer->stop(); + if ( QProgressBar::progress() != mRealProgress ) + QProgressBar::setProgress( mRealProgress ); + } +} + +#include "progressbar.moc" diff --git a/lib/backends/chiasmus/chiasmuslibrary.h b/lib/ui/progressbar.h similarity index 53% copy from lib/backends/chiasmus/chiasmuslibrary.h copy to lib/ui/progressbar.h index 1759b4fc7..41d96796d 100644 --- a/lib/backends/chiasmus/chiasmuslibrary.h +++ b/lib/ui/progressbar.h @@ -1,68 +1,74 @@ -/* -*- mode: C++; c-file-style: "gnu" -*- - chiasmuslibrary.h +/* + progressbar.h This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ +#ifndef __KLEO_PROGRESSBAR_H__ +#define __KLEO_PROGRESSBAR_H__ -#ifndef __KLEO_CHIASMUSLIBRARY_H__ -#define __KLEO_CHIASMUSLIBRARY_H__ - -#include -#include - -class KLibrary; +#include +#include +class QTimer; namespace Kleo { /** - @short small helper class to load xia.o through xia.so and make - the functionality available. + @short A QProgressBar with self-powered busy indicator */ - class ChiasmusLibrary { - ChiasmusLibrary(); - ~ChiasmusLibrary(); + class KDE_EXPORT ProgressBar : public QProgressBar { + Q_OBJECT public: - static const ChiasmusLibrary * instance(); - static void deleteInstance(); + ProgressBar( QWidget * parent=0, const char * name=0, WFlags f=0 ); + + public slots: + void slotProgress( const QString & message, int type, int current, int total ); + void slotProgress( const QString & message, int current, int total ); + /*! reimplementation to support self-powered busy indicator */ + void setProgress( int progress ); + /*! reimplementation to support self-powered busy indicator */ + void setTotalSteps( int total ); + /*! reimplementation to support self-powered busy indicator */ + void reset(); + /*! reimplementation to preserve visibility */ + void setProgress( int cur, int tot ) { QProgressBar::setProgress( cur, tot ); } + + private slots: + void slotBusyTimerTick(); - int perform( const QValueVector & args ) const; private: - typedef int ( *main_func )( int, char** ); - main_func chiasmus( QString * reason=0 ) const; + void fixup( bool ); private: - static ChiasmusLibrary * self; - mutable KLibrary * mXiaLibrary; + QTimer * mBusyTimer; + int mRealProgress; }; - } - -#endif // __KLEO_CHIASMUSLIBRARY_H__ +#endif // __KLEO_PROGRESSBAR_H__ diff --git a/lib/ui/progressdialog.cpp b/lib/ui/progressdialog.cpp new file mode 100644 index 000000000..bb66aca17 --- /dev/null +++ b/lib/ui/progressdialog.cpp @@ -0,0 +1,98 @@ +/* + progressdialog.cpp + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Klarälvdalens Datakonsult AB + + Libkleopatra is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + Libkleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#include "progressdialog.h" + +#include "progressbar.h" + +#include + +#include +#include + +#include + +#include + +Kleo::ProgressDialog::ProgressDialog( Job * job, const QString & baseText, + QWidget * creator, const char * name, WFlags f ) + : QProgressDialog( creator, name, false, f ), mBaseText( baseText ) +{ + assert( job ); + setBar( new ProgressBar( this, "replacement progressbar in Kleo::ProgressDialog" ) ); + + setMinimumDuration( 2000 /*ms*/ ); + setAutoReset( false ); + setAutoClose( false ); + setLabelText( baseText ); + setProgress( 0, 0 ); // activate busy indicator + + connect( job, SIGNAL(progress(const QString&,int,int)), + SLOT(slotProgress(const QString&,int,int)) ); + connect( job, SIGNAL(done()), SLOT(slotDone()) ); + connect( this, SIGNAL(canceled()), + job, SLOT(slotCancel()) ); + + QTimer::singleShot( minimumDuration(), this, SLOT(forceShow()) ); +} + +Kleo::ProgressDialog::~ProgressDialog() { + +} + +void Kleo::ProgressDialog::setMinimumDuration( int ms ) { + if ( 0 < ms && ms < minimumDuration() ) + QTimer::singleShot( ms, this, SLOT(forceShow()) ); + QProgressDialog::setMinimumDuration( ms ); +} + +void Kleo::ProgressDialog::slotProgress( const QString & what, int current, int total ) { + kdDebug(5150) << "Kleo::ProgressDialog::slotProgress( \"" << what << "\", " + << current << ", " << total << " )" << endl; + if ( mBaseText.isEmpty() ) + setLabelText( what ); + else if ( what.isEmpty() ) + setLabelText( mBaseText ); + else + setLabelText( i18n( "%1: %2" ).arg( mBaseText, what ) ); + setProgress( current, total ); +} + +void Kleo::ProgressDialog::slotDone() { + kdDebug(5150) << "Kleo::ProgressDialog::slotDone()" << endl; + hide(); + deleteLater(); +} + + +#include "progressdialog.moc" + diff --git a/lib/backends/chiasmus/chiasmuslibrary.h b/lib/ui/progressdialog.h similarity index 61% copy from lib/backends/chiasmus/chiasmuslibrary.h copy to lib/ui/progressdialog.h index 1759b4fc7..0b419aabb 100644 --- a/lib/backends/chiasmus/chiasmuslibrary.h +++ b/lib/ui/progressdialog.h @@ -1,68 +1,66 @@ -/* -*- mode: C++; c-file-style: "gnu" -*- - chiasmuslibrary.h +/* + progressdialog.h This file is part of libkleopatra, the KDE keymanagement library - Copyright (c) 2005 Klarälvdalens Datakonsult AB + Copyright (c) 2004 Klarälvdalens Datakonsult AB Libkleopatra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libkleopatra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ +#ifndef __KLEO_PROGRESSDIALOG_H__ +#define __KLEO_PROGRESSDIALOG_H__ -#ifndef __KLEO_CHIASMUSLIBRARY_H__ -#define __KLEO_CHIASMUSLIBRARY_H__ - -#include -#include - -class KLibrary; - +#include +#include +#include namespace Kleo { + class Job; + /** - @short small helper class to load xia.o through xia.so and make - the functionality available. + @short A progress dialog for Kleo::Jobs */ - class ChiasmusLibrary { - ChiasmusLibrary(); - ~ChiasmusLibrary(); + class KDE_EXPORT ProgressDialog : public QProgressDialog { + Q_OBJECT public: - static const ChiasmusLibrary * instance(); - static void deleteInstance(); + ProgressDialog( Job * job, const QString & baseText, + QWidget * creator=0, const char * name=0, WFlags f=0 ); + ~ProgressDialog(); - int perform( const QValueVector & args ) const; - private: - typedef int ( *main_func )( int, char** ); - main_func chiasmus( QString * reason=0 ) const; + public slots: + /*! reimplementation */ + void setMinimumDuration( int ms ); + private slots: + void slotProgress( const QString & what, int current, int total ); + void slotDone(); private: - static ChiasmusLibrary * self; - mutable KLibrary * mXiaLibrary; + QString mBaseText; }; } - -#endif // __KLEO_CHIASMUSLIBRARY_H__ +#endif // __KLEO_PROGRESSDIALOG_H__ diff --git a/main.cpp b/main.cpp index 2641b5056..37545502d 100644 --- a/main.cpp +++ b/main.cpp @@ -1,79 +1,84 @@ -/** - KDE Certificate Manager +/* + main.cpp - by Kalle Dalheimer , Jesper - K. Pedersen and - Steffen Hansen + This file is part of Kleopatra, the KDE keymanager + Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB - Copyright (C) 2002 by Klarälvdalens Datakonsult AB + Kleopatra is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. - This software is licensed under the GPL. + Kleopatra is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. */ -#include +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "aboutdata.h" #include "certmanager.h" + +#include + +#include #include #include #include -#include -#include - -CryptPlugWrapper* pWrapper; - -static const char* KGPGCERTMANAGER_VERSION = I18N_NOOP("0.9"); -static const char* DESCRIPTION = I18N_NOOP("Certificate Manager"); +#include +#include int main( int argc, char** argv ) { - KAboutData aboutData( "kgpgcertmanager", I18N_NOOP("KGpgCertManager"), - KGPGCERTMANAGER_VERSION, DESCRIPTION, KAboutData::License_GPL, - "(c) 2002, Steffen Hansen, Jesper Pedersen,\nKalle Dalheimer, Klarälvdalens Datakonsult AB"); - aboutData.addAuthor( "Steffen Hansen", I18N_NOOP("Current Maintainer"), - "hansen@kde.org" ); - aboutData.addAuthor( "Kalle Dalheimer", 0, "kalle@kde.org" ); - aboutData.addAuthor( "Jesper Pedersen", 0, "blackie@kde.org" ); - + AboutData aboutData; + KCmdLineArgs::init(argc, argv, &aboutData); - static KCmdLineOptions options[] = { - { "+name", I18N_NOOP("The name of the plugin"), 0 }, - { "+lib" , I18N_NOOP("The library of the plugin"), 0 }, + static const KCmdLineOptions options[] = { { "external" , I18N_NOOP("Search for external certificates initially"), 0 }, { "query " , I18N_NOOP("Initial query string"), 0 }, - { 0, 0, 0 } // End of options. + { "import-certificate ", I18N_NOOP("Name of certificate file to import"), 0 }, + KCmdLineLastOption// End of options. }; KCmdLineArgs::addCmdLineOptions( options ); - + KApplication app; - + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); - if( args->count() < 2 ) { - KMessageBox::error( 0, - i18n( "Certificate Manager called incorrectly.
Usage: certmanager plugin-name plugin-lib
Certificate Manager will terminate now.
" ), - i18n( "Certificate Manager Error" ) ); - return -1; - } - - QString pluginName = QString::fromLocal8Bit( args->arg( 0 ) ); - QString pluginLib = QString::fromLocal8Bit( args->arg( 1 ) ); - - pWrapper = new CryptPlugWrapper( 0, pluginName, pluginLib, - QString::null, true ); - CryptPlugWrapper::InitStatus initStatus; - QString errorText; - if( !pWrapper->initialize( &initStatus, &errorText ) ) { - KMessageBox::error( 0, - i18n( "The crypto plugin could not be initialized; the error message was %1.
Certificate Manager will terminate now.
" ).arg( errorText ), - i18n( "Certificate Manager Error" ) ); + + KGlobal::locale()->insertCatalogue( "libkleopatra" ); + KGlobal::iconLoader()->addAppDir( "libkleopatra" ); + + if( !Kleo::CryptoBackendFactory::instance()->smime() ) { + KMessageBox::error(0, + i18n( "The crypto plugin could not be initialized.
" + "Certificate Manager will terminate now.
") ); return -2; } + CertManager* manager = new CertManager( args->isSet("external"), - QString::fromLocal8Bit(args->getOption("query")) ); + QString::fromLocal8Bit(args->getOption("query")), + QString::fromLocal8Bit(args->getOption("import-certificate")) ); + args->clear(); manager->show(); - - QObject::connect( qApp, SIGNAL( lastWindowClosed() ), qApp, SLOT( quit() ) ); - int ret = app.exec(); - delete pWrapper; - - return ret; + + return app.exec(); } diff --git a/storedtransferjob.cpp b/storedtransferjob.cpp new file mode 100644 index 000000000..589acd702 --- /dev/null +++ b/storedtransferjob.cpp @@ -0,0 +1,98 @@ +/* + Copyright (C) 2004 David Faure + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "storedtransferjob.h" + +using namespace KIOext; + +#define KIO_ARGS QByteArray packedArgs; QDataStream stream( packedArgs, IO_WriteOnly ); stream + +StoredTransferJob::StoredTransferJob(const KURL& url, int command, + const QByteArray &packedArgs, + const QByteArray &_staticData, + bool showProgressInfo) + : KIO::TransferJob( url, command, packedArgs, _staticData, showProgressInfo ), + m_uploadOffset( 0 ) +{ + connect( this, SIGNAL( data( KIO::Job *, const QByteArray & ) ), + SLOT( slotData( KIO::Job *, const QByteArray & ) ) ); + connect( this, SIGNAL( dataReq( KIO::Job *, QByteArray & ) ), + SLOT( slotDataReq( KIO::Job *, QByteArray & ) ) ); +} + +void StoredTransferJob::setData( const QByteArray& arr ) +{ + Q_ASSERT( m_data.isNull() ); // check that we're only called once + Q_ASSERT( m_uploadOffset == 0 ); // no upload started yet + m_data = arr; +} + +void StoredTransferJob::slotData( KIO::Job *, const QByteArray &data ) +{ + // check for end-of-data marker: + if ( data.size() == 0 ) + return; + unsigned int oldSize = m_data.size(); + m_data.resize( oldSize + data.size(), QGArray::SpeedOptim ); + memcpy( m_data.data() + oldSize, data.data(), data.size() ); +} + +void StoredTransferJob::slotDataReq( KIO::Job *, QByteArray &data ) +{ + // Inspired from kmail's KMKernel::byteArrayToRemoteFile + // send the data in 64 KB chunks + const int MAX_CHUNK_SIZE = 64*1024; + int remainingBytes = m_data.size() - m_uploadOffset; + if( remainingBytes > MAX_CHUNK_SIZE ) { + // send MAX_CHUNK_SIZE bytes to the receiver (deep copy) + data.duplicate( m_data.data() + m_uploadOffset, MAX_CHUNK_SIZE ); + m_uploadOffset += MAX_CHUNK_SIZE; + //kdDebug() << "Sending " << MAX_CHUNK_SIZE << " bytes (" + // << remainingBytes - MAX_CHUNK_SIZE << " bytes remain)\n"; + } else { + // send the remaining bytes to the receiver (deep copy) + data.duplicate( m_data.data() + m_uploadOffset, remainingBytes ); + m_data = QByteArray(); + m_uploadOffset = 0; + //kdDebug() << "Sending " << remainingBytes << " bytes\n"; + } +} + +//// + +StoredTransferJob *KIOext::storedGet( const KURL& url, bool reload, bool showProgressInfo ) +{ + // Send decoded path and encoded query + KIO_ARGS << url; + StoredTransferJob * job = new StoredTransferJob( url, KIO::CMD_GET, packedArgs, QByteArray(), showProgressInfo ); + if (reload) + job->addMetaData("cache", "reload"); + return job; +} + +StoredTransferJob *KIOext::put( const QByteArray& arr, const KURL& url, int permissions, + bool overwrite, bool resume, bool showProgressInfo ) +{ + KIO_ARGS << url << Q_INT8( overwrite ? 1 : 0 ) << Q_INT8( resume ? 1 : 0 ) << permissions; + StoredTransferJob * job = new StoredTransferJob( url, KIO::CMD_PUT, packedArgs, QByteArray(), showProgressInfo ); + job->setData( arr ); + return job; +} + +#include "storedtransferjob.moc" diff --git a/storedtransferjob.h b/storedtransferjob.h new file mode 100644 index 000000000..85b591c6b --- /dev/null +++ b/storedtransferjob.h @@ -0,0 +1,113 @@ +/* + Copyright (C) 2004 David Faure + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef STOREDTRANSFERJOB_H +#define STOREDTRANSFERJOB_H + +#include + +// To be moved to KIO? +namespace KIOext { + +/** + * StoredTransferJob is a TransferJob (for downloading or uploading data) that + * also stores a QByteArray with the data, making it simpler to use than the + * standard TransferJob. + * + * For KIO::get it puts the data into the member QByteArray, so the user + * of this class can get hold of the whole data at once by calling data() + * when the result signal is emitted. + * You should only use StoredTransferJob to download data if you cannot + * process the data by chunks while it's being downloaded, since storing + * everything in a QByteArray can potentially require a lot of memory. + * + * For KIO::put the user of this class simply provides the bytearray from + * the start, and the job takes care of uploading it. + * You should only use StoredTransferJob to upload data if you cannot + * provide the in chunks while it's being uploaded, since storing + * everything in a QByteArray can potentially require a lot of memory. + * + */ +class StoredTransferJob : public KIO::TransferJob { + Q_OBJECT + +public: + /** + * Do not create a StoredTransferJob. Use storedGet() or storedPut() + * instead. + * @param url the url to get or put + * @param command the command to issue + * @param packedArgs the arguments + * @param _staticData additional data to transmit (e.g. in a HTTP Post) + * @param showProgressInfo true to show progress information to the user + */ + StoredTransferJob(const KURL& url, int command, + const QByteArray &packedArgs, + const QByteArray &_staticData, + bool showProgressInfo); + + /** + * Set data to be uploaded. This is for put jobs. + * Automatically called by KIOext::put(const QByteArray &, ...), do not call this yourself. + */ + void setData( const QByteArray& arr ); + + /** + * Get hold of the downloaded data. This is for get jobs. + * You're supposed to call this only from the slot connected to the result() signal. + */ + QByteArray data() const { return m_data; } + +private slots: + void slotData( KIO::Job *job, const QByteArray &data ); + void slotDataReq( KIO::Job *job, QByteArray &data ); +private: + QByteArray m_data; + int m_uploadOffset; +}; + + /** + * Get (a.k.a. read), into a single QByteArray. + * @see StoredTransferJob + * + * @param url the URL of the file + * @param reload true to reload the file, false if it can be taken from the cache + * @param showProgressInfo true to show progress information + * @return the job handling the operation. + */ + StoredTransferJob *storedGet( const KURL& url, bool reload=false, bool showProgressInfo = true ); + + /** + * Put (a.k.a. write) data from a single QByteArray. + * @see StoredTransferJob + * + * @param url Where to write data. + * @param permissions May be -1. In this case no special permission mode is set. + * @param overwrite If true, any existing file will be overwritten. + * @param resume true to resume, false otherwise + * @param showProgressInfo true to show progress information + * @return the job handling the operation. + * @see multi_get() + */ + StoredTransferJob *put( const QByteArray& arr, const KURL& url, int permissions, + bool overwrite, bool resume, bool showProgressInfo = true ); + +} // namespace + +#endif