diff options
Diffstat (limited to 'certmanager/lib/backends')
67 files changed, 7847 insertions, 0 deletions
diff --git a/certmanager/lib/backends/Makefile.am b/certmanager/lib/backends/Makefile.am new file mode 100644 index 000000000..0219d7627 --- /dev/null +++ b/certmanager/lib/backends/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = qgpgme chiasmus diff --git a/certmanager/lib/backends/chiasmus/Makefile.am b/certmanager/lib/backends/chiasmus/Makefile.am new file mode 100644 index 000000000..8a5d85bd4 --- /dev/null +++ b/certmanager/lib/backends/chiasmus/Makefile.am @@ -0,0 +1,16 @@ +INCLUDES = -I$(top_srcdir)/certmanager/lib -I$(top_srcdir)/libkdenetwork $(GPGME_CFLAGS) $(all_includes) + +KDE_CXXFLAGS = '-DGPG_ERR_SOURCE_DEFAULT=((gpg_err_source_t)176)' + +noinst_LTLIBRARIES = libkleopatra_backend_chiasmus.la + +libkleopatra_backend_chiasmus_la_SOURCES = \ + config_data.c \ + obtainkeysjob.cpp \ + symcryptrunprocessbase.cpp \ + chiasmusjob.cpp \ + chiasmuslibrary.cpp \ + chiasmusbackend.cpp + + +METASOURCES = AUTO diff --git a/certmanager/lib/backends/chiasmus/chiasmusbackend.cpp b/certmanager/lib/backends/chiasmus/chiasmusbackend.cpp new file mode 100644 index 000000000..15a63de53 --- /dev/null +++ b/certmanager/lib/backends/chiasmus/chiasmusbackend.cpp @@ -0,0 +1,480 @@ +/* + 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., 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 <config.h> +#endif + +#include "chiasmusbackend.h" + +#include "config_data.h" +#include "obtainkeysjob.h" +#include "chiasmusjob.h" + +#include "kleo/cryptoconfig.h" + +#include <klocale.h> +#include <kconfig.h> +#include <kshell.h> +#include <kdebug.h> + +#include <qstringlist.h> +#include <qvariant.h> +#include <qfileinfo.h> + +#include <map> +#include <memory> + +#include <cassert> + +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<QString>( myVariant ); + template <typename T> 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> { + KURL m; + public: + to( const QVariant & v ) { + m.setPath( v.toString() ); + } + operator KURL() const { return m; } + }; + + template <typename T> + class to< QValueList<T> > { + QValueList<T> m; + public: + to( const QVariant & v ) { + const QValueList<QVariant> vl = v.toList(); + for ( QValueList<QVariant>::const_iterator it = vl.begin(), end = vl.end() ; it != end ; ++it ) + m.push_back( to<T>( *it ) ); + } + operator QValueList<T> () const { return m; } + }; + + template <> + class to<KURL::List> { + KURL::List m; + public: + to( const QVariant & v ) { + // wow, KURL::List is broken... it lacks conversion from and to QVL<KURL>... + m += to< QValueList<KURL> >( v ); + } + operator KURL::List() const { return m; } + }; + + + // from<> is the demarshaller. See to<> for why this is a class... + + template <typename T> + struct from_helper : public QVariant { + from_helper( const T & t ) : QVariant( t ) {} + }; + + template <typename T> + QVariant from( const T & t ) { + return from_helper<T>( t ); + } + + // some special types: + template <> struct from_helper<bool> : public QVariant { + from_helper( bool b ) : QVariant( b, int() ) {} + }; + template <> struct from_helper<KURL> : public QVariant { + from_helper( const KURL & url ) : QVariant( url.path() ) {} + }; + template <typename T> struct from_helper< QValueList<T> > : public QVariant { + from_helper( const QValueList<T> & l ) { + QValueList<QVariant> result; + for ( typename QValueList<T>::const_iterator it = l.begin(), end = l.end() ; it != end ; ++it ) + result.push_back( from( *it ) ); + QVariant::operator=( result ); + } + }; + template <> struct from_helper<KURL::List> : public from_helper< QValueList<KURL> > { + from_helper( const KURL::List & l ) : from_helper< QValueList<KURL> >( 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 isReadOnly() const { return false; } + 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<Level>( kleo_chiasmus_config_entries[mIdx].level ); } + ArgType argType() const { return static_cast<ArgType>( 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<int> intValueList() const { return to< QValueList<int> >( mValue ); } + QValueList<unsigned int> uintValueList() const { return to< QValueList<unsigned int> >( mValue ); } + KURL::List urlValueList() const { + if ( argType() != ArgType_Path && argType()!= ArgType_DirPath ) return mValue.toStringList(); + else return to<KURL::List>( 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<int> & l ) { setValue( from( l ) ); } + void setUIntValueList( const QValueList<unsigned int> & 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>() << 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<QVariant>() << data.defaults.integer; + else + return data.defaults.integer; + case ArgType_UInt: + if ( isList() ) + return QValueList<QVariant>() << data.defaults.unsigned_integer; + else + return data.defaults.unsigned_integer; + case ArgType_Path: + case ArgType_DirPath: + if ( isList() ) + return QValueList<QVariant>() << QString::fromLatin1( data.defaults.path ); + else + return QString::fromLatin1( data.defaults.path ); + case ArgType_URL: + case ArgType_LDAPURL: + if ( isList() ) + return QValueList<QVariant>() << QString::fromLatin1( data.defaults.url ); + else + return QString::fromLatin1( data.defaults.url ); + } + } + + class ChiasmusGeneralGroup : public Kleo::CryptoConfigGroup { + mutable std::map<QString,ChiasmusConfigEntry*> 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<QString,ChiasmusConfigEntry*>::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<QString,ChiasmusConfigEntry*>::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 QString& ) 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<QString,QVariant> & 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<Protocol> 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/certmanager/lib/backends/chiasmus/chiasmusbackend.h b/certmanager/lib/backends/chiasmus/chiasmusbackend.h new file mode 100644 index 000000000..6d51cad77 --- /dev/null +++ b/certmanager/lib/backends/chiasmus/chiasmusbackend.h @@ -0,0 +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., 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/certmanager/lib/backends/chiasmus/chiasmusjob.cpp b/certmanager/lib/backends/chiasmus/chiasmusjob.cpp new file mode 100644 index 000000000..3ac7513df --- /dev/null +++ b/certmanager/lib/backends/chiasmus/chiasmusjob.cpp @@ -0,0 +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., 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 <config.h> +#endif + +#include "chiasmusjob.h" +#include "chiasmusbackend.h" +#include "symcryptrunprocessbase.h" + +#include "kleo/cryptoconfig.h" +#include "ui/passphrasedialog.h" + +#include <gpg-error.h> + +#include <kshell.h> +#include <klocale.h> +#include <kdebug.h> +#include <kmessagebox.h> + +#include <qtimer.h> +#include <qfileinfo.h> +#include <qvariant.h> + +#include <memory> + +#include <cassert> + +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/certmanager/lib/backends/chiasmus/chiasmusjob.h b/certmanager/lib/backends/chiasmus/chiasmusjob.h new file mode 100644 index 000000000..6393a0905 --- /dev/null +++ b/certmanager/lib/backends/chiasmus/chiasmusjob.h @@ -0,0 +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., 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 <qstringlist.h> + +#include <gpgmepp/context.h> + +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/certmanager/lib/backends/chiasmus/chiasmuslibrary.cpp b/certmanager/lib/backends/chiasmus/chiasmuslibrary.cpp new file mode 100644 index 000000000..2e3225492 --- /dev/null +++ b/certmanager/lib/backends/chiasmus/chiasmuslibrary.cpp @@ -0,0 +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., 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 <klibloader.h> +#include <kdebug.h> +#include <klocale.h> + +#include <qfile.h> + +#include <vector> +#include <algorithm> + +#include <cassert> +#include <cstdlib> +#include <cstring> + +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<QCString> & 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<QCString> & args ) const { + if ( main_func func = chiasmus() ) + return func( args.size(), ArgvProvider( args ).argv() ); + else + return -1; +} diff --git a/certmanager/lib/backends/chiasmus/chiasmuslibrary.h b/certmanager/lib/backends/chiasmus/chiasmuslibrary.h new file mode 100644 index 000000000..b04e162b4 --- /dev/null +++ b/certmanager/lib/backends/chiasmus/chiasmuslibrary.h @@ -0,0 +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., 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 <qvaluevector.h> +#include <qcstring.h> + +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<QCString> & 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/certmanager/lib/backends/chiasmus/config_data.c b/certmanager/lib/backends/chiasmus/config_data.c new file mode 100644 index 000000000..bb3f33916 --- /dev/null +++ b/certmanager/lib/backends/chiasmus/config_data.c @@ -0,0 +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., 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 <config.h> +#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/certmanager/lib/backends/chiasmus/config_data.h b/certmanager/lib/backends/chiasmus/config_data.h new file mode 100644 index 000000000..c5c7b6c4e --- /dev/null +++ b/certmanager/lib/backends/chiasmus/config_data.h @@ -0,0 +1,34 @@ +#ifndef __KLEO__CHIASMUS_CONFIG_DATA_H__ +#define __KLEO__CHIASMUS_CONFIG_DATA_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +struct kleo_chiasmus_config_data { + const char * name; + const char * description; + int level; + int type; + union { + const char * path; /* must be first, see config_data.c */ + const char * string; + const char * url; + struct { unsigned int value : 1; unsigned int numTimesSet : 31; } boolean; + int integer; + unsigned int unsigned_integer; + } defaults; + unsigned int is_optional : 1; + unsigned int is_list : 1; + unsigned int is_runtime : 1; +}; + +extern const struct kleo_chiasmus_config_data kleo_chiasmus_config_entries[]; +extern const unsigned int kleo_chiasmus_config_entries_dim; + +#ifdef __cplusplus +} +#endif + +#endif /* __KLEO__CHIASMUS_CONFIG_DATA_H__ */ + diff --git a/certmanager/lib/backends/chiasmus/configure.in.in b/certmanager/lib/backends/chiasmus/configure.in.in new file mode 100644 index 000000000..8cea56ad3 --- /dev/null +++ b/certmanager/lib/backends/chiasmus/configure.in.in @@ -0,0 +1,16 @@ +dnl +dnl Check for C99 designated initializers: +dnl +AC_LANG_SAVE +AC_LANG_C +AC_MSG_CHECKING([for C99 designated initializers]) +AC_TRY_COMPILE([ + union { int one; const char * two } foo = { .two = "Hello" }; +], [], [ + AC_DEFINE(HAVE_C99_INITIALIZERS, 1, [Define to 1 if your C compiler support C99 designated initializers]) + AC_MSG_RESULT([yes]) +], [ + AC_MSG_RESULT([no]) +]) + +AC_LANG_RESTORE diff --git a/certmanager/lib/backends/chiasmus/obtainkeysjob.cpp b/certmanager/lib/backends/chiasmus/obtainkeysjob.cpp new file mode 100644 index 000000000..a9de8d658 --- /dev/null +++ b/certmanager/lib/backends/chiasmus/obtainkeysjob.cpp @@ -0,0 +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., 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 <config.h> +#endif + +#include "obtainkeysjob.h" + +#include "chiasmusbackend.h" + +#include "kleo/cryptoconfig.h" + +#include <klocale.h> +#include <kmessagebox.h> +#include <kshell.h> + +#include <qdir.h> +#include <qstringlist.h> +#include <qvariant.h> +#include <qtimer.h> +#include <qfileinfo.h> + +#include <gpg-error.h> + +#include <cassert> + +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/certmanager/lib/backends/chiasmus/obtainkeysjob.h b/certmanager/lib/backends/chiasmus/obtainkeysjob.h new file mode 100644 index 000000000..4b8392d46 --- /dev/null +++ b/certmanager/lib/backends/chiasmus/obtainkeysjob.h @@ -0,0 +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., 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 <qstringlist.h> + +#include <gpgmepp/context.h> + +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: + <code> + Kleo::SpecialJob * job = + protocol->specialJob("x-obtain-keys", QMap<QString,QVariant>()); + </code> + + 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/certmanager/lib/backends/chiasmus/symcryptrunprocessbase.cpp b/certmanager/lib/backends/chiasmus/symcryptrunprocessbase.cpp new file mode 100644 index 000000000..1b8627252 --- /dev/null +++ b/certmanager/lib/backends/chiasmus/symcryptrunprocessbase.cpp @@ -0,0 +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., 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 <ktempfile.h> +#include <kdebug.h> +#include <kshell.h> + +#include <qtimer.h> +#include <qfile.h> + +#include <cstring> + +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/certmanager/lib/backends/chiasmus/symcryptrunprocessbase.h b/certmanager/lib/backends/chiasmus/symcryptrunprocessbase.h new file mode 100644 index 000000000..d74db60cc --- /dev/null +++ b/certmanager/lib/backends/chiasmus/symcryptrunprocessbase.h @@ -0,0 +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., 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 <kprocess.h> + +#include <qcstring.h> + +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/certmanager/lib/backends/kpgp/Makefile.am b/certmanager/lib/backends/kpgp/Makefile.am new file mode 100644 index 000000000..ad350f22c --- /dev/null +++ b/certmanager/lib/backends/kpgp/Makefile.am @@ -0,0 +1,12 @@ +INCLUDES = -I$(top_srcdir)/libkdenetwork \ + -I$(top_srcdir)/certmanager/lib \ + -I$(top_srcdir)/libkpgp \ + $(GPGME_CFLAGS) $(all_includes) + +noinst_LTLIBRARIES = libkleopatra_backend_kpgp.la + +libkleopatra_backend_kpgp_la_SOURCES = \ + kpgpbackendbase.cpp kpgpwrapper.cpp \ + kpgpkeylistjob.cpp + +METASOURCES = AUTO diff --git a/certmanager/lib/backends/kpgp/gpg1backend.h b/certmanager/lib/backends/kpgp/gpg1backend.h new file mode 100644 index 000000000..f9413accf --- /dev/null +++ b/certmanager/lib/backends/kpgp/gpg1backend.h @@ -0,0 +1,52 @@ +/* -*- mode: C++; c-file-style: "gnu" -*- + gpg1backend.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_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/certmanager/lib/backends/kpgp/kpgpbackendbase.cpp b/certmanager/lib/backends/kpgp/kpgpbackendbase.cpp new file mode 100644 index 000000000..2d4d17ab2 --- /dev/null +++ b/certmanager/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 <config.h> +#endif + +#include "kpgpbackendbase.h" + +#include "pgp2backend.h" +#include "pgp5backend.h" +#include "pgp6backend.h" +#include "gpg1backend.h" + +#include <klocale.h> + +#include <qstring.h> + +#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/certmanager/lib/backends/kpgp/kpgpbackendbase.h b/certmanager/lib/backends/kpgp/kpgpbackendbase.h new file mode 100644 index 000000000..854e800c3 --- /dev/null +++ b/certmanager/lib/backends/kpgp/kpgpbackendbase.h @@ -0,0 +1,73 @@ +/* -*- mode: C++; c-file-style: "gnu" -*- + kpgpbackendbase.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_KPGPBACKENDBASE_H__ +#define __KLEO_KPGPBACKENDBASE_H__ + +#include "kleo/cryptobackend.h" + +#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 QString; +class KpgpWrapper; + +namespace Kleo { + + class KpgpBackendBase : public Kleo::CryptoBackend { + public: + KpgpBackendBase(); + ~KpgpBackendBase(); + + CryptoConfig * config() const { return 0; } + Protocol * openpgp() const; + Protocol * smime() const { return 0; } + + bool supportsOpenPGP() const { return true; } + bool supportsSMIME() const { return false; } + + bool checkForOpenPGP( QString * reason=0 ) const; + bool checkForSMIME( QString * reason=0 ) const; + private: + mutable KpgpWrapper * mOpenPGPProtocol; + }; + +} + + +#endif // __KLEO_KPGPBACKENDBASE_H__ diff --git a/certmanager/lib/backends/kpgp/kpgpkeylistjob.cpp b/certmanager/lib/backends/kpgp/kpgpkeylistjob.cpp new file mode 100644 index 000000000..4c328adee --- /dev/null +++ b/certmanager/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 <kloecker@kde.org> + + 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 <config.h> +#endif + +#include "kpgpkeylistjob.h" + +#include <kpgpbase.h> +#include <kpgpkey.h> + +#include <gpgmepp/key.h> +#include <gpgmepp/keylistresult.h> + +#include <gpgme.h> + +#include <qtimer.h> + +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +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<GpgME::Key> keys; + GpgME::KeyListResult res = exec( mPatterns, mSecretOnly, keys ); + for ( std::vector<GpgME::Key>::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<GpgME::Key> & 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/certmanager/lib/backends/kpgp/kpgpkeylistjob.h b/certmanager/lib/backends/kpgp/kpgpkeylistjob.h new file mode 100644 index 000000000..779680c2d --- /dev/null +++ b/certmanager/lib/backends/kpgp/kpgpkeylistjob.h @@ -0,0 +1,79 @@ +/* -*- mode: C++ -*- + kpgpkeylistjob.h + + This file is part of libkleopatra, the KDE keymanagement library + Copyright (c) 2004 Ingo Kloecker <kloecker@kde.org> + + 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_KPGPKEYLISTJOB_H__ +#define __KLEO_KPGPKEYLISTJOB_H__ + +#include <kleo/keylistjob.h> + +#include <qstringlist.h> + +namespace GpgME { + class Error; + class Context; + class Key; +} + +namespace Kpgp { + class Base; +} + +namespace Kleo { + + class KpgpKeyListJob : public KeyListJob { + Q_OBJECT + public: + KpgpKeyListJob( Kpgp::Base * pgpBase ); + ~KpgpKeyListJob(); + + /*! \reimp from KeyListJob */ + GpgME::Error start( const QStringList & patterns, bool secretOnly ); + + /*! \reimp from KeyListJob */ + GpgME::KeyListResult exec( const QStringList & patterns, bool secretOnly, + std::vector<GpgME::Key> & keys ); + + /*! \reimp from Job */ + void slotCancel() { /*FIXME*/ } + + private slots: + void slotDoIt(); + + private: + Kpgp::Base * mPgpBase; + QStringList mPatterns; + bool mSecretOnly; + }; + +} + +#endif // __KLEO_KPGPKEYLISTJOB_H__ diff --git a/certmanager/lib/backends/kpgp/kpgpwrapper.cpp b/certmanager/lib/backends/kpgp/kpgpwrapper.cpp new file mode 100644 index 000000000..20d885dd5 --- /dev/null +++ b/certmanager/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 <kloecker@kde.org> + + 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 <config.h> +#endif + +#include "kpgpwrapper.h" + +#include "kpgpbackendbase.h" + +#include <kpgpbase.h> + +#include <backends/kpgp/kpgpkeylistjob.h> +//#include <backends/kpgp/kpgpencryptjob.h> +//#include <backends/kpgp/kpgpdecryptjob.h> +//#include <backends/kpgp/kpgpsignjob.h> +//#include <backends/kpgp/kpgpverifydetachedjob.h> +//#include <backends/kpgp/kpgpverifyopaquejob.h> +//#include <backends/kpgp/kpgpkeygenerationjob.h> +//#include <backends/kpgp/kpgpimportjob.h> +//#include <backends/kpgp/kpgpexportjob.h> +//#include <backends/kpgp/kpgpsecretkeyexportjob.h> +//#include <backends/kpgp/kpgpdownloadjob.h> +//#include <backends/kpgp/kpgpdeletejob.h> +//#include <backends/kpgp/kpgpsignencryptjob.h> +//#include <backends/kpgp/kpgpdecryptverifyjob.h> +//#include <backends/kpgp/kpgpcryptoconfig.h> + +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/certmanager/lib/backends/kpgp/kpgpwrapper.h b/certmanager/lib/backends/kpgp/kpgpwrapper.h new file mode 100644 index 000000000..182661ec4 --- /dev/null +++ b/certmanager/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 <kloecker@kde.org> + + 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 <kleo/cryptobackend.h> + +#include <qstring.h> + +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/certmanager/lib/backends/kpgp/pgp2backend.h b/certmanager/lib/backends/kpgp/pgp2backend.h new file mode 100644 index 000000000..fc053a20c --- /dev/null +++ b/certmanager/lib/backends/kpgp/pgp2backend.h @@ -0,0 +1,52 @@ +/* -*- mode: C++; c-file-style: "gnu" -*- + pgp2backend.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_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/certmanager/lib/backends/kpgp/pgp5backend.h b/certmanager/lib/backends/kpgp/pgp5backend.h new file mode 100644 index 000000000..bf323b6fb --- /dev/null +++ b/certmanager/lib/backends/kpgp/pgp5backend.h @@ -0,0 +1,52 @@ +/* -*- mode: C++; c-file-style: "gnu" -*- + pgp5backend.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_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/certmanager/lib/backends/kpgp/pgp6backend.h b/certmanager/lib/backends/kpgp/pgp6backend.h new file mode 100644 index 000000000..827cf239b --- /dev/null +++ b/certmanager/lib/backends/kpgp/pgp6backend.h @@ -0,0 +1,52 @@ +/* -*- mode: C++; c-file-style: "gnu" -*- + pgp6backend.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_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/certmanager/lib/backends/qgpgme/Makefile.am b/certmanager/lib/backends/qgpgme/Makefile.am new file mode 100644 index 000000000..a7336a029 --- /dev/null +++ b/certmanager/lib/backends/qgpgme/Makefile.am @@ -0,0 +1,34 @@ +#KDE_OPTIONS = nofinal + +INCLUDES = -I$(top_srcdir)/libkdenetwork \ + -I$(top_srcdir)/certmanager/lib \ + $(GPGME_CFLAGS) $(all_includes) + +noinst_LTLIBRARIES = libkleopatra_backend_qgpgme.la + +libkleopatra_backend_qgpgme_la_SOURCES = \ + gnupgprocessbase.cpp \ + qgpgmeprogresstokenmapper.cpp \ + \ + qgpgmebackend.cpp \ + \ + qgpgmejob.cpp \ + \ + qgpgmekeylistjob.cpp \ + qgpgmekeygenerationjob.cpp \ + qgpgmeimportjob.cpp \ + qgpgmeexportjob.cpp \ + qgpgmesecretkeyexportjob.cpp \ + qgpgmedownloadjob.cpp \ + qgpgmedeletejob.cpp \ + qgpgmeencryptjob.cpp \ + qgpgmedecryptjob.cpp \ + qgpgmesignjob.cpp \ + qgpgmeverifydetachedjob.cpp \ + qgpgmeverifyopaquejob.cpp \ + qgpgmesignencryptjob.cpp \ + qgpgmedecryptverifyjob.cpp \ + qgpgmecryptoconfig.cpp \ + qgpgmerefreshkeysjob.cpp + +METASOURCES = AUTO diff --git a/certmanager/lib/backends/qgpgme/gnupgprocessbase.cpp b/certmanager/lib/backends/qgpgme/gnupgprocessbase.cpp new file mode 100644 index 000000000..2d3ca7409 --- /dev/null +++ b/certmanager/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 <kdebug.h> +#include <kurl.h> + +#include <qsocketnotifier.h> +#include <qtextcodec.h> +#include <qstringlist.h> + +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <assert.h> + +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<QCString>::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/certmanager/lib/backends/qgpgme/gnupgprocessbase.h b/certmanager/lib/backends/qgpgme/gnupgprocessbase.h new file mode 100644 index 000000000..73e31e295 --- /dev/null +++ b/certmanager/lib/backends/qgpgme/gnupgprocessbase.h @@ -0,0 +1,91 @@ +/* + gnupgprocessbase.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_GNUPGPROCESSBASE_H__ +#define __KLEO_GNUPGPROCESSBASE_H__ + +#include <kprocess.h> + +namespace Kleo { + + /** + * @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 <mutz@kde.org> + */ + class GnuPGProcessBase : public KProcess { + Q_OBJECT + public: + 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 ); + + private: + void parseStatusOutput(); + + private: + class Private; + Private * d; + protected: + /*! reimplementation */ + void virtual_hook( int id, void * data ); + }; + +} + +#endif // __KLEO_GNUPGPROCESSBASE_H__ diff --git a/certmanager/lib/backends/qgpgme/qgpgmebackend.cpp b/certmanager/lib/backends/qgpgme/qgpgmebackend.cpp new file mode 100644 index 000000000..8256522ae --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmebackend.cpp @@ -0,0 +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., 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 <config.h> +#endif + +#include "qgpgmebackend.h" + +#include "qgpgmecryptoconfig.h" +#include "cryptplugwrapper.h" + +#include <gpgmepp/context.h> +#include <gpgmepp/engineinfo.h> + +#include <klocale.h> +#include <kstandarddirs.h> + +#include <qfile.h> +#include <qstring.h> + +Kleo::QGpgMEBackend::QGpgMEBackend() + : Kleo::CryptoBackend(), + mCryptoConfig( 0 ), + mOpenPGPProtocol( 0 ), + mSMIMEProtocol( 0 ) +{ + GpgME::initializeLibrary(); +} + +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 ) == 0; +} + +const char * Kleo::QGpgMEBackend::enumerateProtocols( int i ) const { + switch ( i ) { + case 0: return OpenPGP; + case 1: return SMIME; + default: return 0; + } +} diff --git a/certmanager/lib/backends/qgpgme/qgpgmebackend.h b/certmanager/lib/backends/qgpgme/qgpgmebackend.h new file mode 100644 index 000000000..fae2dd68e --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmebackend.h @@ -0,0 +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., 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/certmanager/lib/backends/qgpgme/qgpgmecryptoconfig.cpp b/certmanager/lib/backends/qgpgme/qgpgmecryptoconfig.cpp new file mode 100644 index 000000000..86eab99b4 --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmecryptoconfig.cpp @@ -0,0 +1,837 @@ +/* + 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., 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 <kdebug.h> +#include <kprocio.h> +#include <errno.h> +#include <kmessagebox.h> +#include <klocale.h> + +#include <assert.h> +#include <ktempfile.h> +#include <qfile.h> +#include <stdlib.h> +#include <qtextcodec.h> + +// 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; + +static const int GPGCONF_FLAG_GROUP = 1; +static const int GPGCONF_FLAG_OPTIONAL = 2; +static const int GPGCONF_FLAG_LIST = 4; +static const int GPGCONF_FLAG_RUNTIME = 8; +static const int GPGCONF_FLAG_DEFAULT = 16; // fixed default value available +static const int GPGCONF_FLAG_DEFAULT_DESC = 32; // runtime default value available +static const int GPGCONF_FLAG_NOARG_DESC = 64; // option with optional arg; special meaning if no arg set +static const int GPGCONF_FLAG_NO_CHANGE = 128; // readonly +// 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("<qt>Failed to execute gpgconf:<br>%1</qt>"); + 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<QGpgMECryptoConfig*>( this )->runGpgConf( true ); + QDictIterator<QGpgMECryptoConfigComponent> 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<QGpgMECryptoConfig*>( this )->runGpgConf( false ); + return mComponents.find( name ); +} + +void QGpgMECryptoConfig::sync( bool runtime ) +{ + QDictIterator<QGpgMECryptoConfigComponent> 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 <component>, 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( "<nogroup>", QString::null, 0 ); + mCurrentGroupName = "<nogroup>"; + } + 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<QGpgMECryptoConfigGroup> 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<QGpgMECryptoConfigEntry *> dirtyEntries; + + // Collect all dirty entries + QDictIterator<QGpgMECryptoConfigGroup> groupit( mGroups ); + for( ; groupit.current(); ++groupit ) { + QDictIterator<QGpgMECryptoConfigEntry> 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 <component> + 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( QString::fromLocal8Bit( strerror( rc ) ) ); + kdWarning(5150) << k_funcinfo << ":" << strerror( rc ) << endl; + KMessageBox::error(0, wmsg); + } + else + { + QValueList<QGpgMECryptoConfigEntry *>::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<Kleo::CryptoConfigEntry::Level>( level ) ) +{ + mEntries.setAutoDelete( true ); +} + +QStringList QGpgMECryptoConfigGroup::entryList() const +{ + QDictIterator<QGpgMECryptoConfigEntry> 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<QVariant> 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::isReadOnly() const +{ + return mFlags & GPGCONF_FLAG_NO_CHANGE; +} + +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<int> QGpgMECryptoConfigEntry::intValueList() const +{ + Q_ASSERT( mArgType == ArgType_Int ); + Q_ASSERT( isList() ); + QValueList<int> ret; + QValueList<QVariant> lst = mValue.toList(); + for( QValueList<QVariant>::const_iterator it = lst.begin(); it != lst.end(); ++it ) { + ret.append( (*it).toInt() ); + } + return ret; +} + +QValueList<unsigned int> QGpgMECryptoConfigEntry::uintValueList() const +{ + Q_ASSERT( mArgType == ArgType_UInt ); + Q_ASSERT( isList() ); + QValueList<unsigned int> ret; + QValueList<QVariant> lst = mValue.toList(); + for( QValueList<QVariant>::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<int>& lst ) +{ + QValueList<QVariant> ret; + for( QValueList<int>::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<unsigned int>& lst ) +{ + QValueList<QVariant> ret; + for( QValueList<unsigned int>::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<QVariant> lst = mValue.toList(); + for( QValueList<QVariant>::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/certmanager/lib/backends/qgpgme/qgpgmecryptoconfig.h b/certmanager/lib/backends/qgpgme/qgpgmecryptoconfig.h new file mode 100644 index 000000000..bfcb8e5ca --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmecryptoconfig.h @@ -0,0 +1,186 @@ +/* + 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., 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 <kleo/cryptoconfig.h> +#include <qdict.h> +#include <qstringlist.h> +#include <qobject.h> +#include <qvariant.h> +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<QGpgMECryptoConfigComponent> 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<QGpgMECryptoConfigGroup> 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<QGpgMECryptoConfigEntry> 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 isReadOnly() const; + bool isList() const; + bool isRuntime() const; + Level level() const { return static_cast<Level>( mLevel ); } + ArgType argType() const { return static_cast<ArgType>( 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<int> intValueList() const; + QValueList<unsigned int> 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<int>& ); + void setUIntValueList( const QValueList<unsigned int>& ); + 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 : 8; // bitfield with 8 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/certmanager/lib/backends/qgpgme/qgpgmedecryptjob.cpp b/certmanager/lib/backends/qgpgme/qgpgmedecryptjob.cpp new file mode 100644 index 000000000..17905555e --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmedecryptjob.cpp @@ -0,0 +1,91 @@ +/* + 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 <config.h> +#endif + +#include "qgpgmedecryptjob.h" + +#include <qgpgme/eventloopinteractor.h> +#include <qgpgme/dataprovider.h> + +#include <gpgmepp/context.h> +#include <gpgmepp/decryptionresult.h> +#include <gpgmepp/data.h> + +#include <assert.h> + +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(); + getAuditLog(); + return result; +} + +void Kleo::QGpgMEDecryptJob::doOperationDoneEvent( const GpgME::Error & ) { + emit result( mCtx->decryptionResult(), mOutDataDataProvider->data() ); +} + +#include "qgpgmedecryptjob.moc" diff --git a/certmanager/lib/backends/qgpgme/qgpgmedecryptjob.h b/certmanager/lib/backends/qgpgme/qgpgmedecryptjob.h new file mode 100644 index 000000000..7fc89dff2 --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmedecryptjob.h @@ -0,0 +1,74 @@ +/* + qgpgmedecryptjob.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_QGPGMEDECRYPTJOB_H__ +#define __KLEO_QGPGMEDECRYPTJOB_H__ + +#include <kleo/decryptjob.h> + +#include "qgpgmejob.h" + +#include <qcstring.h> + +namespace GpgME { + class Error; + class Context; +} + +namespace Kleo { + + class QGpgMEDecryptJob : public DecryptJob, private QGpgMEJob { + Q_OBJECT QGPGME_JOB + public: + QGpgMEDecryptJob( GpgME::Context * context ); + ~QGpgMEDecryptJob(); + + /*! \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: + void doOperationDoneEvent( const GpgME::Error & e ); + void setup( const QByteArray & cipherText ); + }; + +} + +#endif // __KLEO_QGPGMEDECRYPTJOB_H__ diff --git a/certmanager/lib/backends/qgpgme/qgpgmedecryptverifyjob.cpp b/certmanager/lib/backends/qgpgme/qgpgmedecryptverifyjob.cpp new file mode 100644 index 000000000..02cf1ef28 --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmedecryptverifyjob.cpp @@ -0,0 +1,95 @@ +/* + 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 <config.h> +#endif + +#include "qgpgmedecryptverifyjob.h" + +#include <qgpgme/eventloopinteractor.h> +#include <qgpgme/dataprovider.h> + +#include <gpgmepp/context.h> +#include <gpgmepp/decryptionresult.h> +#include <gpgmepp/verificationresult.h> +#include <gpgmepp/data.h> + +#include <assert.h> + +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<GpgME::DecryptionResult,GpgME::VerificationResult> +Kleo::QGpgMEDecryptVerifyJob::exec( const QByteArray & cipherText, QByteArray & plainText ) { + setup( cipherText ); + const std::pair<GpgME::DecryptionResult,GpgME::VerificationResult> result = + mCtx->decryptAndVerify( *mInData, *mOutData ); + plainText = mOutDataDataProvider->data(); + getAuditLog(); + return result; +} + +void Kleo::QGpgMEDecryptVerifyJob::doOperationDoneEvent( const GpgME::Error & ) { + emit result( mCtx->decryptionResult(), + mCtx->verificationResult(), + mOutDataDataProvider->data() ); +} + +#include "qgpgmedecryptverifyjob.moc" diff --git a/certmanager/lib/backends/qgpgme/qgpgmedecryptverifyjob.h b/certmanager/lib/backends/qgpgme/qgpgmedecryptverifyjob.h new file mode 100644 index 000000000..a39188746 --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmedecryptverifyjob.h @@ -0,0 +1,75 @@ +/* + qgpgmedecryptverifyjob.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_QGPGMEDECRYPTVERIFYJOB_H__ +#define __KLEO_QGPGMEDECRYPTVERIFYJOB_H__ + +#include <kleo/decryptverifyjob.h> + +#include "qgpgmejob.h" + +#include <qcstring.h> +#include <kdepimmacros.h> + +namespace GpgME { + class Error; + class Context; +} + +namespace Kleo { + + class KDE_EXPORT QGpgMEDecryptVerifyJob : public DecryptVerifyJob, private QGpgMEJob { + Q_OBJECT QGPGME_JOB + public: + QGpgMEDecryptVerifyJob( GpgME::Context * context ); + ~QGpgMEDecryptVerifyJob(); + + /*! \reimp from DecryptVerifyJob */ + GpgME::Error start( const QByteArray & cipherText ); + + /*! \reimp from DecryptVerifyJob */ + std::pair<GpgME::DecryptionResult,GpgME::VerificationResult> + exec( const QByteArray & cipherText, QByteArray & plainText ); + + private slots: + void slotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e ) { + QGpgMEJob::doSlotOperationDoneEvent( context, e ); + } + + private: + void doOperationDoneEvent( const GpgME::Error & e ); + void setup( const QByteArray & ); + }; + +} + +#endif // __KLEO_QGPGMEDECRYPTVERIFYJOB_H__ diff --git a/certmanager/lib/backends/qgpgme/qgpgmedeletejob.cpp b/certmanager/lib/backends/qgpgme/qgpgmedeletejob.cpp new file mode 100644 index 000000000..c06907eea --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmedeletejob.cpp @@ -0,0 +1,70 @@ +/* + qgpgmedeletejob.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 <config.h> +#endif + +#include "qgpgmedeletejob.h" + +#include <qgpgme/eventloopinteractor.h> + +#include <gpgmepp/context.h> + +#include <assert.h> + +Kleo::QGpgMEDeleteJob::QGpgMEDeleteJob( GpgME::Context * context ) + : DeleteJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMEDeleteJob" ), + QGpgMEJob( this, context ) +{ + assert( context ); +} + +Kleo::QGpgMEDeleteJob::~QGpgMEDeleteJob() { +} + +GpgME::Error Kleo::QGpgMEDeleteJob::start( const GpgME::Key & key, bool allowSecretKeyDeletion ) { + + 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 ); +} + +#include "qgpgmedeletejob.moc" diff --git a/certmanager/lib/backends/qgpgme/qgpgmedeletejob.h b/certmanager/lib/backends/qgpgme/qgpgmedeletejob.h new file mode 100644 index 000000000..9dec128f7 --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmedeletejob.h @@ -0,0 +1,68 @@ +/* + qgpgmedeletejob.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_QGPGMEDELETEJOB_H__ +#define __KLEO_QGPGMEDELETEJOB_H__ + +#include <kleo/deletejob.h> + +#include "qgpgmejob.h" + +namespace GpgME { + class Error; + class Context; + class Key; +} + +namespace Kleo { + + class QGpgMEDeleteJob : public DeleteJob, private QGpgMEJob { + Q_OBJECT QGPGME_JOB + public: + QGpgMEDeleteJob( GpgME::Context * context ); + ~QGpgMEDeleteJob(); + + /*! \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: + void doOperationDoneEvent( const GpgME::Error & e ); + }; + +} + +#endif // __KLEO_QGPGMEDELETEJOB_H__ diff --git a/certmanager/lib/backends/qgpgme/qgpgmedownloadjob.cpp b/certmanager/lib/backends/qgpgme/qgpgmedownloadjob.cpp new file mode 100644 index 000000000..6ee771a04 --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmedownloadjob.cpp @@ -0,0 +1,78 @@ +/* + qgpgmedownloadjob.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 <config.h> +#endif + +#include "qgpgmedownloadjob.h" + +#include <qgpgme/eventloopinteractor.h> +#include <qgpgme/dataprovider.h> + +#include <gpgmepp/context.h> +#include <gpgmepp/data.h> + +#include <qstringlist.h> + +#include <assert.h> + +Kleo::QGpgMEDownloadJob::QGpgMEDownloadJob( GpgME::Context * context ) + : DownloadJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMEDownloadJob" ), + QGpgMEJob( this, context ) +{ + assert( context ); +} + +Kleo::QGpgMEDownloadJob::~QGpgMEDownloadJob() { +} + +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() ); +} + +#include "qgpgmedownloadjob.moc" diff --git a/certmanager/lib/backends/qgpgme/qgpgmedownloadjob.h b/certmanager/lib/backends/qgpgme/qgpgmedownloadjob.h new file mode 100644 index 000000000..1402b127c --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmedownloadjob.h @@ -0,0 +1,67 @@ +/* + qgpgmedownloadjob.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_QGPGMEDOWNLOADJOB_H__ +#define __KLEO_QGPGMEDOWNLOADJOB_H__ + +#include <kleo/downloadjob.h> + +#include "qgpgmejob.h" + +namespace GpgME { + class Error; + class Context; +} + +namespace Kleo { + + class QGpgMEDownloadJob : public DownloadJob, private QGpgMEJob { + Q_OBJECT QGPGME_JOB + public: + QGpgMEDownloadJob( GpgME::Context * context ); + ~QGpgMEDownloadJob(); + + /*! \reimp from DownloadJob */ + GpgME::Error start( const QStringList & fingerprints ); + + private: + void doOperationDoneEvent( const GpgME::Error & e ); + + private slots: + void slotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e ) { + QGpgMEJob::doSlotOperationDoneEvent( context, e ); + } + }; + +} + +#endif // __KLEO_QGPGMEDOWNLOADJOB_H__ diff --git a/certmanager/lib/backends/qgpgme/qgpgmeencryptjob.cpp b/certmanager/lib/backends/qgpgme/qgpgmeencryptjob.cpp new file mode 100644 index 000000000..3f223fc56 --- /dev/null +++ b/certmanager/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 <config.h> +#endif + +#include "qgpgmeencryptjob.h" + +#include "ui/messagebox.h" + +#include <qgpgme/eventloopinteractor.h> +#include <qgpgme/dataprovider.h> + +#include <gpgmepp/context.h> +#include <gpgmepp/encryptionresult.h> +#include <gpgmepp/data.h> + +#include <klocale.h> + +#include <assert.h> + +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<GpgME::Key> & 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(); + mResult = GpgME::EncryptionResult( err ); + return err; +} + +GpgME::EncryptionResult Kleo::QGpgMEEncryptJob::exec( const std::vector<GpgME::Key> & 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(); + getAuditLog(); + return mResult; +} + +void Kleo::QGpgMEEncryptJob::doOperationDoneEvent( const GpgME::Error & ) { + emit result( mResult = mCtx->encryptionResult(), mOutDataDataProvider->data() ); +} + +void Kleo::QGpgMEEncryptJob::showErrorDialog( QWidget * parent, const QString & caption ) const { + if ( mResult.error() && !mResult.error().isCanceled() ) + Kleo::MessageBox::error( parent, mResult, this, caption ); +} + +#include "qgpgmeencryptjob.moc" diff --git a/certmanager/lib/backends/qgpgme/qgpgmeencryptjob.h b/certmanager/lib/backends/qgpgme/qgpgmeencryptjob.h new file mode 100644 index 000000000..362fb4e06 --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmeencryptjob.h @@ -0,0 +1,86 @@ +/* + qgpgmeencryptjob.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_QGPGMEENCRYPTJOB_H__ +#define __KLEO_QGPGMEENCRYPTJOB_H__ + +#include <kleo/encryptjob.h> + +#include "qgpgmejob.h" + +#include <gpgmepp/encryptionresult.h> + +#include <qcstring.h> + +namespace GpgME { + class Error; + class Context; + class Key; +} + +namespace Kleo { + + class QGpgMEEncryptJob : public EncryptJob, private QGpgMEJob { + Q_OBJECT QGPGME_JOB + public: + QGpgMEEncryptJob( GpgME::Context * context ); + ~QGpgMEEncryptJob(); + + /*! \reimp from EncryptJob */ + GpgME::Error start( const std::vector<GpgME::Key> & recipients, + const QByteArray & plainText, bool alwaysTrust ); + + /*! \reimp from EncryptJob */ + GpgME::EncryptionResult exec( const std::vector<GpgME::Key> & 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 ); + void setup( const QByteArray & ); + + private: + GpgME::EncryptionResult mResult; + }; + +} + +#endif // __KLEO_QGPGMEENCRYPTJOB_H__ diff --git a/certmanager/lib/backends/qgpgme/qgpgmeexportjob.cpp b/certmanager/lib/backends/qgpgme/qgpgmeexportjob.cpp new file mode 100644 index 000000000..c9274f3b7 --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmeexportjob.cpp @@ -0,0 +1,78 @@ +/* + qgpgmeexportjob.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 <config.h> +#endif + +#include "qgpgmeexportjob.h" + +#include <qgpgme/eventloopinteractor.h> +#include <qgpgme/dataprovider.h> + +#include <gpgmepp/context.h> +#include <gpgmepp/data.h> + +#include <qstringlist.h> + +#include <assert.h> + +Kleo::QGpgMEExportJob::QGpgMEExportJob( GpgME::Context * context ) + : ExportJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMEExportJob" ), + QGpgMEJob( this, context ) +{ + assert( context ); +} + +Kleo::QGpgMEExportJob::~QGpgMEExportJob() { +} + +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() ); +} + +#include "qgpgmeexportjob.moc" diff --git a/certmanager/lib/backends/qgpgme/qgpgmeexportjob.h b/certmanager/lib/backends/qgpgme/qgpgmeexportjob.h new file mode 100644 index 000000000..8b799b583 --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmeexportjob.h @@ -0,0 +1,69 @@ +/* + qgpgmeexportjob.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_QGPGMEEXPORTJOB_H__ +#define __KLEO_QGPGMEEXPORTJOB_H__ + +#include <kleo/exportjob.h> + +#include "qgpgmejob.h" + +#include <qcstring.h> + +namespace GpgME { + class Error; + class Context; +} + +namespace Kleo { + + class QGpgMEExportJob : public ExportJob, private QGpgMEJob { + Q_OBJECT QGPGME_JOB + public: + QGpgMEExportJob( GpgME::Context * context ); + ~QGpgMEExportJob(); + + /*! \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: + void doOperationDoneEvent( const GpgME::Error & e ); + }; + +} + +#endif // __KLEO_QGPGMEEXPORTJOB_H__ diff --git a/certmanager/lib/backends/qgpgme/qgpgmeimportjob.cpp b/certmanager/lib/backends/qgpgme/qgpgmeimportjob.cpp new file mode 100644 index 000000000..fd1251b65 --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmeimportjob.cpp @@ -0,0 +1,86 @@ +/* + qgpgmeimportjob.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 <config.h> +#endif + +#include "qgpgmeimportjob.h" + +#include <qgpgme/eventloopinteractor.h> +#include <qgpgme/dataprovider.h> + +#include <gpgmepp/context.h> +#include <gpgmepp/importresult.h> +#include <gpgmepp/data.h> + +#include <assert.h> + +Kleo::QGpgMEImportJob::QGpgMEImportJob( GpgME::Context * context ) + : ImportJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMEImportJob" ), + QGpgMEJob( this, context ) +{ + assert( context ); +} + +Kleo::QGpgMEImportJob::~QGpgMEImportJob() { +} + +void Kleo::QGpgMEImportJob::setup( const QByteArray & keyData ) { + assert( !mInData ); + + createInData( keyData ); +} + +GpgME::Error Kleo::QGpgMEImportJob::start( const QByteArray & keyData ) { + setup( keyData ); + + hookupContextToEventLoopInteractor(); + + const GpgME::Error err = mCtx->startKeyImport( *mInData ); + + if ( err ) + deleteLater(); + return err; +} + +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() ); +} + + +#include "qgpgmeimportjob.moc" diff --git a/certmanager/lib/backends/qgpgme/qgpgmeimportjob.h b/certmanager/lib/backends/qgpgme/qgpgmeimportjob.h new file mode 100644 index 000000000..8c2ee1ad4 --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmeimportjob.h @@ -0,0 +1,73 @@ +/* + qgpgmeimportjob.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_QGPGMEIMPORTJOB_H__ +#define __KLEO_QGPGMEIMPORTJOB_H__ + +#include <kleo/importjob.h> + +#include "qgpgmejob.h" + +#include <qcstring.h> + +namespace GpgME { + class Error; + class Context; +} + +namespace Kleo { + + class QGpgMEImportJob : public ImportJob, private QGpgMEJob { + Q_OBJECT QGPGME_JOB + public: + QGpgMEImportJob( GpgME::Context * context ); + ~QGpgMEImportJob(); + + /*! \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: + void doOperationDoneEvent( const GpgME::Error & e ); + void setup( const QByteArray & ); + }; + +} + +#endif // __KLEO_QGPGMEIMPORTJOB_H__ diff --git a/certmanager/lib/backends/qgpgme/qgpgmejob.cpp b/certmanager/lib/backends/qgpgme/qgpgmejob.cpp new file mode 100644 index 000000000..897e5ff7c --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmejob.cpp @@ -0,0 +1,304 @@ +/* + 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 <config.h> +#endif + +#include "qgpgmejob.h" +#include "qgpgmeprogresstokenmapper.h" + +#include <kleo/job.h> +#include <ui/passphrasedialog.h> + +#include <qgpgme/eventloopinteractor.h> +#include <qgpgme/dataprovider.h> + +#include <gpgmepp/context.h> +#include <gpgmepp/data.h> + +#include <klocale.h> +#include <kstandarddirs.h> + +#include <qstring.h> +#include <qstringlist.h> + +#include <algorithm> + +#include <assert.h> +#include <string.h> + +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<GpgME::Key> & signers ) { + mCtx->clearSigningKeys(); + for ( std::vector<GpgME::Key>::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() ); +} + +static const unsigned int GetAuditLogFlags = GpgME::Context::AuditLogWithHelp|GpgME::Context::HtmlAuditLog; + +static QString audit_log_as_html( GpgME::Context * ctx ) { + if ( !ctx ) + return QString(); + QGpgME::QByteArrayDataProvider dp; + GpgME::Data data( &dp ); + assert( !data.isNull() ); + if ( const GpgME::Error err = ctx->getAuditLog( data, GetAuditLogFlags ) ) + return QString(); + else + return QString::fromUtf8( dp.data().data() ); +} + +void Kleo::QGpgMEJob::doSlotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e ) { + if ( context == mCtx ) { + getAuditLog(); + doEmitDoneSignal(); + doOperationDoneEvent( e ); + mThis->deleteLater(); + } +} + +void Kleo::QGpgMEJob::getAuditLog() { + mAuditLogAsHtml = audit_log_as_html( mCtx ); +} + +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:<br/> %1 (retry)" ) : + i18n( "You need a passphrase to unlock the secret key for user:<br/> %1" ); + msg = msg.arg( QString::fromUtf8( useridHint ) ) + "<br/><br/>"; + msg.prepend( "<qt>" ); + 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." ) + "<br/>"; + 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 += "<br/>"; + msg += i18n( "For information on how to set up gpg-agent, see %1" ) + .arg( "http://kmail.kde.org/kmail-pgpmime-howto.html" ); + msg += "<br/><br/>"; + 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/certmanager/lib/backends/qgpgme/qgpgmejob.h b/certmanager/lib/backends/qgpgme/qgpgmejob.h new file mode 100644 index 000000000..da7acf1c9 --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmejob.h @@ -0,0 +1,160 @@ +/* + 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 <gpgmepp/interfaces/progressprovider.h> +#include <gpgmepp/interfaces/passphraseprovider.h> + +#include <gpgmepp/key.h> + +#include <qcstring.h> +#include <qstring.h> + +#include <vector> +#include <kdepimmacros.h> + +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<GpgME::Key> & signers ); + /*! Call this to implement a slotOperationDoneEvent() */ + void doSlotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e ); + /*! Call this to extract the audit log from mCtx */ + void getAuditLog(); + + // + // only boring stuff below this line... + // + + protected: + virtual void doEmitProgressSignal( const QString & what, int current, int total ) = 0; + virtual void doEmitDoneSignal() = 0; + void doSlotCancel(); + QString auditLogAsHtml() const { return mAuditLogAsHtml; } + + 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; + QString mAuditLogAsHtml; + }; + +} + +#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 make_auditLogAsHtml private: QString auditLogAsHtml() const { return QGpgMEJob::auditLogAsHtml(); } +#define QGPGME_JOB make_slot_cancel make_progress_emitter make_done_emitter make_auditLogAsHtml + +#endif // __KLEO_QGPGMEJOB_H__ diff --git a/certmanager/lib/backends/qgpgme/qgpgmekeygenerationjob.cpp b/certmanager/lib/backends/qgpgme/qgpgmekeygenerationjob.cpp new file mode 100644 index 000000000..a0ab78f23 --- /dev/null +++ b/certmanager/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 <config.h> +#endif + +#include "qgpgmekeygenerationjob.h" + +#include <qgpgme/dataprovider.h> +#include <qgpgme/eventloopinteractor.h> + +#include <gpgmepp/context.h> +#include <gpgmepp/keygenerationresult.h> +#include <gpgmepp/data.h> + +#include <assert.h> + +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/certmanager/lib/backends/qgpgme/qgpgmekeygenerationjob.h b/certmanager/lib/backends/qgpgme/qgpgmekeygenerationjob.h new file mode 100644 index 000000000..973aeb12d --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmekeygenerationjob.h @@ -0,0 +1,78 @@ +/* + qgpgmekeygenerationjob.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_QGPGMEKEYGENERATIONJOB_H__ +#define __KLEO_QGPGMEKEYGENERATIONJOB_H__ + +#include <kleo/keygenerationjob.h> + +#include "qgpgmejob.h" +#include <kdepimmacros.h> + +namespace GpgME { + class Error; + class Context; + class Key; + class Data; +} + +namespace QGpgME { + class QByteArrayDataProvider; +} + +namespace Kleo { + + class KDE_EXPORT QGpgMEKeyGenerationJob : public KeyGenerationJob, private QGpgMEJob { + Q_OBJECT QGPGME_JOB + public: + 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 ); + } + + private: + void doOperationDoneEvent( const GpgME::Error & e ); + + private: + QGpgME::QByteArrayDataProvider * mPubKeyDataProvider; + GpgME::Data * mPubKey; + }; + +} + +#endif // __KLEO_QGPGMEKEYGENERATIONJOB_H__ diff --git a/certmanager/lib/backends/qgpgme/qgpgmekeylistjob.cpp b/certmanager/lib/backends/qgpgme/qgpgmekeylistjob.cpp new file mode 100644 index 000000000..9c87e3ef6 --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmekeylistjob.cpp @@ -0,0 +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., 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 <config.h> +#endif + +#include "qgpgmekeylistjob.h" + +#include <qgpgme/eventloopinteractor.h> + +#include <gpgmepp/key.h> +#include <gpgmepp/context.h> +#include <gpgmepp/keylistresult.h> +#include <gpg-error.h> + +#include <kmessagebox.h> +#include <klocale.h> +#include <kdebug.h> + +#include <qstringlist.h> + +#include <algorithm> + +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +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<GpgME::Key> & 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<GpgME::Key> & 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( "<qt><p>An error occurred while fetching " + "the keys from the backend:</p>" + "<p><b>%1</b></p></qt>" ) + .arg( QString::fromLocal8Bit( mResult.error().asString() ) ); + KMessageBox::error( parent, msg, caption ); +} + +#include "qgpgmekeylistjob.moc" diff --git a/certmanager/lib/backends/qgpgme/qgpgmekeylistjob.h b/certmanager/lib/backends/qgpgme/qgpgmekeylistjob.h new file mode 100644 index 000000000..8320e0134 --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmekeylistjob.h @@ -0,0 +1,81 @@ +/* + 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., 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_QGPGMEKEYLISTJOB_H__ +#define __KLEO_QGPGMEKEYLISTJOB_H__ + +#include <kleo/keylistjob.h> + +#include <gpgmepp/keylistresult.h> + +#include "qgpgmejob.h" + +namespace GpgME { + class Error; + class Context; + class Key; +} + +namespace Kleo { + + class QGpgMEKeyListJob : public KeyListJob, private QGpgMEJob { + Q_OBJECT QGPGME_JOB + public: + QGpgMEKeyListJob( GpgME::Context * context ); + ~QGpgMEKeyListJob(); + + /*! \reimp from KeyListJob */ + GpgME::Error start( const QStringList & patterns, bool secretOnly ); + + /*! \reimp from KeyListJob */ + GpgME::KeyListResult exec( const QStringList & patterns, bool secretOnly, std::vector<GpgME::Key> & keys ); + + /*! \reimp from Job */ + void showErrorDialog( QWidget * parent, const QString & caption ) const; + + private slots: + void slotNextKeyEvent( GpgME::Context * context, const GpgME::Key & key ); + void slotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e ); + + private: + void doOperationDoneEvent( const GpgME::Error &) {} // unused, we implement slotOperationDoneEvent ourselves. + void setup( const QStringList &, bool ); + GpgME::KeyListResult attemptSyncKeyListing( std::vector<GpgME::Key> & ); + + private: + GpgME::KeyListResult mResult; + bool mSecretOnly; + }; + +} + +#endif // __KLEO_QGPGMEKEYLISTJOB_H__ diff --git a/certmanager/lib/backends/qgpgme/qgpgmeprogresstokenmapper.cpp b/certmanager/lib/backends/qgpgme/qgpgmeprogresstokenmapper.cpp new file mode 100644 index 000000000..3b6ae35eb --- /dev/null +++ b/certmanager/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 <config.h> +#endif + +#include "qgpgmeprogresstokenmapper.h" + +#include <klocale.h> + +#include <qstring.h> + +#include <assert.h> +#include <map> + +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 exercise 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<int,Desc> > 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<int,Desc>::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/certmanager/lib/backends/qgpgme/qgpgmeprogresstokenmapper.h b/certmanager/lib/backends/qgpgme/qgpgmeprogresstokenmapper.h new file mode 100644 index 000000000..d0a8da6c3 --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmeprogresstokenmapper.h @@ -0,0 +1,58 @@ +/* + qgpgmeprogresstokenmapper.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_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/certmanager/lib/backends/qgpgme/qgpgmerefreshkeysjob.cpp b/certmanager/lib/backends/qgpgme/qgpgmerefreshkeysjob.cpp new file mode 100644 index 000000000..325306e8c --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmerefreshkeysjob.cpp @@ -0,0 +1,207 @@ +/* + 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., 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 <config.h> +#endif + +#include "qgpgmerefreshkeysjob.h" + +#include "gnupgprocessbase.h" +#include "qgpgmeprogresstokenmapper.h" + +#include <kdebug.h> + +#include <gpgmepp/context.h> + +#include <qgpgme/eventloopinteractor.h> + +#include <qstringlist.h> + +#include <gpg-error.h> + +#include <assert.h> + +Kleo::QGpgMERefreshKeysJob::QGpgMERefreshKeysJob() + : RefreshKeysJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMERefreshKeysJob" ), + mProcess( 0 ), + mError( 0 ) +{ + +} + +Kleo::QGpgMERefreshKeysJob::~QGpgMERefreshKeysJob() { + +} + +GpgME::Error Kleo::QGpgMERefreshKeysJob::start( const QStringList & patterns ) { + assert( mPatternsToDo.empty() ); + + 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 -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" << "-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(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::Stderr ) ) { + mError = gpg_err_make( GPG_ERR_SOURCE_GPGSM, GPG_ERR_ENOENT ); // what else? + deleteLater(); + return mError; + } else + return 0; +} + +void Kleo::QGpgMERefreshKeysJob::slotCancel() { + if ( mProcess ) + mProcess->kill(); + mProcess = 0; + mError = gpg_err_make( GPG_ERR_SOURCE_GPGSM, GPG_ERR_CANCELED ); +} + +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::QGpgMERefreshKeysJob::slotStatus() not recognising ERROR with < 2 args!" << endl; + return; + } + const int source = (*++it).toInt( &ok ); + if ( !ok ) { + 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::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::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::QGpgMERefreshKeysJob::slotStatus() expected number for \"cur\", got something else" << endl; + return; + } + ok = false; + const int total = (*++it).toInt( &ok ); + if ( !ok ) { + 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::QGpgMERefreshKeysJob::slotStderr( KProcess *, char *, int ) { + // implement? or not? +} + +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 ); + deleteLater(); +} + +#include "qgpgmerefreshkeysjob.moc" diff --git a/certmanager/lib/backends/qgpgme/qgpgmerefreshkeysjob.h b/certmanager/lib/backends/qgpgme/qgpgmerefreshkeysjob.h new file mode 100644 index 000000000..a0132f223 --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmerefreshkeysjob.h @@ -0,0 +1,80 @@ +/* + qgpgmerefreshkeysjob.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_QGPGMEREFRESHKEYSJOB_H__ +#define __KLEO_QGPGMEREFRESHKEYSJOB_H__ + +#include <kleo/refreshkeysjob.h> + +#include <qstringlist.h> + +namespace Kleo { + class GnuPGProcessBase; +} + +namespace GpgME { + class Error; +} + +class KProcess; + +namespace Kleo { + + class QGpgMERefreshKeysJob : public RefreshKeysJob { + Q_OBJECT + public: + 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 * ); + + private: + GpgME::Error startAProcess(); + + private: + GnuPGProcessBase * mProcess; + int mError; + QStringList mPatternsToDo; + }; + +} + +#endif // __KLEO_QGPGMEREFRESHKEYSJOB_H__ diff --git a/certmanager/lib/backends/qgpgme/qgpgmesecretkeyexportjob.cpp b/certmanager/lib/backends/qgpgme/qgpgmesecretkeyexportjob.cpp new file mode 100644 index 000000000..0ce543cf9 --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmesecretkeyexportjob.cpp @@ -0,0 +1,196 @@ +/* + 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., 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 <config.h> +#endif + +#include "qgpgmesecretkeyexportjob.h" + +#include "gnupgprocessbase.h" +#include "qgpgmeprogresstokenmapper.h" + +#include <kdebug.h> + +#include <gpgmepp/context.h> +#include <gpgmepp/data.h> + +#include <qgpgme/eventloopinteractor.h> + +#include <qstringlist.h> + +#include <gpg-error.h> + +#include <string.h> +#include <assert.h> + +Kleo::QGpgMESecretKeyExportJob::QGpgMESecretKeyExportJob( bool armour, const QString& charset ) + : ExportJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMESecretKeyExportJob" ), + mProcess( 0 ), + mError( 0 ), + mArmour( armour ), + mCharset( charset ) +{ + +} + +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: obtain the path to gpgsm from gpgme, so we use the same instance. + *mProcess << "gpgsm" << "--export-secret-key-p12"; + if ( mArmour ) + *mProcess << "--armor"; + if ( !mCharset.isEmpty() ) + *mProcess << "--p12-charset" << mCharset; + *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/certmanager/lib/backends/qgpgme/qgpgmesecretkeyexportjob.h b/certmanager/lib/backends/qgpgme/qgpgmesecretkeyexportjob.h new file mode 100644 index 000000000..5f5e3b69c --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmesecretkeyexportjob.h @@ -0,0 +1,85 @@ +/* + qgpgmesecretkeyexportjob.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_QGPGMESECRETKEYEXPORTJOB_H__ +#define __KLEO_QGPGMESECRETKEYEXPORTJOB_H__ + +#include <kleo/exportjob.h> + +#include <qcstring.h> + +namespace Kleo { + class GnuPGProcessBase; +} + +namespace GpgME { + class Error; + class Data; +} + +namespace QGpgME { + class QByteArrayDataProvider; +} + +class KProcess; + +namespace Kleo { + + class QGpgMESecretKeyExportJob : public ExportJob { + Q_OBJECT + public: + QGpgMESecretKeyExportJob( bool armour, const QString& charset ); + ~QGpgMESecretKeyExportJob(); + + /*! \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: + GnuPGProcessBase * mProcess; + QByteArray mKeyData; + int mError; + bool mArmour; + QString mCharset; + }; + +} + +#endif // __KLEO_QGPGMESECRETKEYEXPORTJOB_H__ diff --git a/certmanager/lib/backends/qgpgme/qgpgmesignencryptjob.cpp b/certmanager/lib/backends/qgpgme/qgpgmesignencryptjob.cpp new file mode 100644 index 000000000..fae748478 --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmesignencryptjob.cpp @@ -0,0 +1,121 @@ +/* + 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 <config.h> +#endif + +#include "qgpgmesignencryptjob.h" + +#include "ui/messagebox.h" + +#include <qgpgme/eventloopinteractor.h> +#include <qgpgme/dataprovider.h> + +#include <gpgmepp/context.h> +#include <gpgmepp/data.h> +#include <gpgmepp/key.h> + +#include <klocale.h> + +#include <assert.h> + +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<GpgME::Key> & signers, + const QByteArray & plainText ) { + assert( !mInData ); + assert( !mOutData ); + + createInData( plainText ); + createOutData(); + + return setSigningKeys( signers ); +} + +GpgME::Error Kleo::QGpgMESignEncryptJob::start( const std::vector<GpgME::Key> & signers, + const std::vector<GpgME::Key> & 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(); + mResult.first = GpgME::SigningResult( err ); + mResult.second = GpgME::EncryptionResult( err ); + return err; +} + +std::pair<GpgME::SigningResult,GpgME::EncryptionResult> +Kleo::QGpgMESignEncryptJob::exec( const std::vector<GpgME::Key> & signers, + const std::vector<GpgME::Key> & 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 ; + mResult = mCtx->signAndEncrypt( recipients, *mInData, *mOutData, flags ); + cipherText = mOutDataDataProvider->data(); + getAuditLog(); + return mResult; +} + +void Kleo::QGpgMESignEncryptJob::doOperationDoneEvent( const GpgME::Error & ) { + mResult.first = mCtx->signingResult(); + mResult.second = mCtx->encryptionResult(); + emit result( mResult.first, mResult.second, mOutDataDataProvider->data() ); +} + +void Kleo::QGpgMESignEncryptJob::showErrorDialog( QWidget * parent, const QString & caption ) const { + if ( mResult.first.error() && !mResult.first.error().isCanceled() || + mResult.second.error() && !mResult.second.error().isCanceled() ) + Kleo::MessageBox::error( parent, mResult.first, mResult.second, this, caption ); +} + +#include "qgpgmesignencryptjob.moc" diff --git a/certmanager/lib/backends/qgpgme/qgpgmesignencryptjob.h b/certmanager/lib/backends/qgpgme/qgpgmesignencryptjob.h new file mode 100644 index 000000000..a826edcbf --- /dev/null +++ b/certmanager/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 <kleo/signencryptjob.h> + +#include "qgpgmejob.h" + +#include <gpgmepp/signingresult.h> +#include <gpgmepp/encryptionresult.h> + +#include <qcstring.h> + +#include <utility> + +#include <kdepimmacros.h> +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<GpgME::Key> & signers, + const std::vector<GpgME::Key> & recipients, + const QByteArray & plainText, bool alwaysTrust ); + + std::pair<GpgME::SigningResult,GpgME::EncryptionResult> + exec( const std::vector<GpgME::Key> & signers, + const std::vector<GpgME::Key> & 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<GpgME::Key> &, + const QByteArray & ); + private: + std::pair<GpgME::SigningResult,GpgME::EncryptionResult> mResult; + }; + +} + +#endif // __KLEO_QGPGMESIGNENCRYPTJOB_H__ diff --git a/certmanager/lib/backends/qgpgme/qgpgmesignjob.cpp b/certmanager/lib/backends/qgpgme/qgpgmesignjob.cpp new file mode 100644 index 000000000..84485ad5b --- /dev/null +++ b/certmanager/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 <config.h> +#endif + +#include "qgpgmesignjob.h" + +#include "ui/messagebox.h" + +#include <qgpgme/eventloopinteractor.h> +#include <qgpgme/dataprovider.h> + +#include <gpgmepp/context.h> +#include <gpgmepp/signingresult.h> +#include <gpgmepp/data.h> +#include <gpgmepp/key.h> + +#include <klocale.h> + +#include <assert.h> + +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<GpgME::Key> & signers, + const QByteArray & plainText ) { + assert( !mInData ); + assert( !mOutData ); + + createInData( plainText ); + createOutData(); + + return setSigningKeys( signers ); +} + +GpgME::Error Kleo::QGpgMESignJob::start( const std::vector<GpgME::Key> & 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(); + mResult = GpgME::SigningResult( err ); + return err; +} + +GpgME::SigningResult Kleo::QGpgMESignJob::exec( const std::vector<GpgME::Key> & 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(); + getAuditLog(); + return mResult; +} + +void Kleo::QGpgMESignJob::doOperationDoneEvent( const GpgME::Error & ) { + emit result( mResult = mCtx->signingResult(), mOutDataDataProvider->data() ); +} + +void Kleo::QGpgMESignJob::showErrorDialog( QWidget * parent, const QString & caption ) const { + if ( mResult.error() && !mResult.error().isCanceled() ) + Kleo::MessageBox::error( parent, mResult, this, caption ); +} + +#include "qgpgmesignjob.moc" diff --git a/certmanager/lib/backends/qgpgme/qgpgmesignjob.h b/certmanager/lib/backends/qgpgme/qgpgmesignjob.h new file mode 100644 index 000000000..c2589b477 --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmesignjob.h @@ -0,0 +1,87 @@ +/* + qgpgmesignjob.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_QGPGMESIGNJOB_H__ +#define __KLEO_QGPGMESIGNJOB_H__ + +#include <kleo/signjob.h> + +#include "qgpgmejob.h" + +#include <gpgmepp/signingresult.h> + +#include <qcstring.h> + +namespace GpgME { + class Error; + class Context; + class Key; +} + +namespace Kleo { + + class QGpgMESignJob : public SignJob, private QGpgMEJob { + Q_OBJECT QGPGME_JOB + public: + QGpgMESignJob( GpgME::Context * context ); + ~QGpgMESignJob(); + + /*! \reimp from SignJob */ + GpgME::Error start( const std::vector<GpgME::Key> & signers, + const QByteArray & plainText, + GpgME::Context::SignatureMode mode ); + + /*! \reimp from SignJob */ + GpgME::SigningResult exec( const std::vector<GpgME::Key> & 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 ); + } + + private: + void doOperationDoneEvent( const GpgME::Error & e ); + GpgME::Error setup( const std::vector<GpgME::Key> &, const QByteArray & ); + + private: + GpgME::SigningResult mResult; + }; + +} + +#endif // __KLEO_QGPGMESIGNJOB_H__ diff --git a/certmanager/lib/backends/qgpgme/qgpgmeverifydetachedjob.cpp b/certmanager/lib/backends/qgpgme/qgpgmeverifydetachedjob.cpp new file mode 100644 index 000000000..cc1186373 --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmeverifydetachedjob.cpp @@ -0,0 +1,96 @@ +/* + 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 <config.h> +#endif + +#include "qgpgmeverifydetachedjob.h" + +#include <qgpgme/eventloopinteractor.h> +#include <qgpgme/dataprovider.h> + +#include <gpgmepp/context.h> +#include <gpgmepp/verificationresult.h> +#include <gpgmepp/data.h> + +#include <assert.h> + +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 ); + const GpgME::VerificationResult r = mCtx->verifyDetachedSignature( *mInData, *mOutData ); + getAuditLog(); + return r; +} + +void Kleo::QGpgMEVerifyDetachedJob::doOperationDoneEvent( const GpgME::Error & ) { + emit result( mCtx->verificationResult() ); +} + + +#include "qgpgmeverifydetachedjob.moc" diff --git a/certmanager/lib/backends/qgpgme/qgpgmeverifydetachedjob.h b/certmanager/lib/backends/qgpgme/qgpgmeverifydetachedjob.h new file mode 100644 index 000000000..76141fb80 --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmeverifydetachedjob.h @@ -0,0 +1,75 @@ +/* + qgpgmeverifydetachedjob.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_QGPGMEVERIFYDETACHEDJOB_H__ +#define __KLEO_QGPGMEVERIFYDETACHEDJOB_H__ + +#include <kleo/verifydetachedjob.h> + +#include "qgpgmejob.h" + +#include <qcstring.h> + +namespace GpgME { + class Error; + class Context; +} + +namespace Kleo { + + class QGpgMEVerifyDetachedJob : public VerifyDetachedJob, private QGpgMEJob { + Q_OBJECT QGPGME_JOB + public: + QGpgMEVerifyDetachedJob( GpgME::Context * context ); + ~QGpgMEVerifyDetachedJob(); + + /*! \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: + void doOperationDoneEvent( const GpgME::Error & e ); + void setup( const QByteArray &, const QByteArray & ); + }; + +} + +#endif // __KLEO_QGPGMEVERIFYDETACHEDJOB_H__ diff --git a/certmanager/lib/backends/qgpgme/qgpgmeverifyopaquejob.cpp b/certmanager/lib/backends/qgpgme/qgpgmeverifyopaquejob.cpp new file mode 100644 index 000000000..15f075963 --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmeverifyopaquejob.cpp @@ -0,0 +1,91 @@ +/* + 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 <config.h> +#endif + +#include "qgpgmeverifyopaquejob.h" + +#include <qgpgme/eventloopinteractor.h> +#include <qgpgme/dataprovider.h> + +#include <gpgmepp/context.h> +#include <gpgmepp/verificationresult.h> +#include <gpgmepp/data.h> + +#include <assert.h> + +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(); + getAuditLog(); + return res; +} + +void Kleo::QGpgMEVerifyOpaqueJob::doOperationDoneEvent( const GpgME::Error & ) { + emit result( mCtx->verificationResult(), mOutDataDataProvider->data() ); +} + + +#include "qgpgmeverifyopaquejob.moc" diff --git a/certmanager/lib/backends/qgpgme/qgpgmeverifyopaquejob.h b/certmanager/lib/backends/qgpgme/qgpgmeverifyopaquejob.h new file mode 100644 index 000000000..2c167fb1d --- /dev/null +++ b/certmanager/lib/backends/qgpgme/qgpgmeverifyopaquejob.h @@ -0,0 +1,73 @@ +/* + qgpgmeverifyopaquejob.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_QGPGMEVERIFYOPAQUEJOB_H__ +#define __KLEO_QGPGMEVERIFYOPAQUEJOB_H__ + +#include <kleo/verifyopaquejob.h> + +#include "qgpgmejob.h" + +#include <qcstring.h> + +namespace GpgME { + class Error; + class Context; +} + +namespace Kleo { + + class QGpgMEVerifyOpaqueJob : public VerifyOpaqueJob, private QGpgMEJob { + Q_OBJECT QGPGME_JOB + public: + QGpgMEVerifyOpaqueJob( GpgME::Context * context ); + ~QGpgMEVerifyOpaqueJob(); + + /*! \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: + void doOperationDoneEvent( const GpgME::Error & e ); + void setup( const QByteArray & ); + }; + +} + +#endif // __KLEO_QGPGMEVERIFYOPAQUEJOB_H__ |