libkleo
chiasmusbackend.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "chiasmusbackend.h"
00034
00035 #include "config_data.h"
00036 #include "obtainkeysjob.h"
00037 #include "chiasmusjob.h"
00038
00039 #include "kleo/cryptoconfig.h"
00040
00041 #include <klocale.h>
00042 #include <kconfig.h>
00043 #include <kshell.h>
00044 #include <kdebug.h>
00045 #include <kconfiggroup.h>
00046
00047 #include <QStringList>
00048 #include <QVariant>
00049 #include <QFileInfo>
00050
00051 #include <QList>
00052
00053 #include <map>
00054 #include <memory>
00055
00056 #include <cassert>
00057
00058 namespace {
00059
00060
00061
00062
00063
00064
00065
00066
00067 template <typename T> class to {};
00068
00069 #define MAKE_TO( type, func ) \
00070 template <> \
00071 class to< type > { \
00072 type m; \
00073 public: \
00074 to( const QVariant & v ) : m( v.func() ) {} \
00075 operator type() const { return m; } \
00076 }
00077
00078 MAKE_TO( int, toInt );
00079 MAKE_TO( unsigned int, toUInt );
00080
00081 template <>
00082 class to<KUrl> {
00083 KUrl m;
00084 public:
00085 to( const QVariant & v ) {
00086 m.setPath( v.toString() );
00087 }
00088 operator KUrl() const { return m; }
00089 };
00090
00091 template <typename T>
00092 class to< QList<T> > {
00093 QList<T> m;
00094 public:
00095 to( const QVariant & v ) {
00096 const QList<QVariant> vl = v.toList();
00097 for ( QList<QVariant>::const_iterator it = vl.begin(), end = vl.end() ; it != end ; ++it )
00098 m.push_back( to<T>( *it ) );
00099 }
00100 operator QList<T> () const { return m; }
00101 };
00102
00103 template <>
00104 class to<KUrl::List> {
00105 KUrl::List m;
00106 public:
00107 to( const QVariant & v ) {
00108
00109 m += to< QList<KUrl> >( v );
00110 }
00111 operator KUrl::List() const { return m; }
00112 };
00113
00114
00115
00116
00117 template <typename T>
00118 struct from_helper : public QVariant {
00119 from_helper( const T & t ) : QVariant( t ) {}
00120 };
00121
00122 template <typename T>
00123 QVariant from( const T & t ) {
00124 return from_helper<T>( t );
00125 }
00126
00127
00128 template <> struct from_helper<bool> : public QVariant {
00129 from_helper( bool b ) : QVariant( b ) {}
00130 };
00131 template <> struct from_helper<KUrl> : public QVariant {
00132 from_helper( const KUrl & url ) : QVariant( url.path() ) {}
00133 };
00134 template <typename T> struct from_helper< QList<T> > : public QVariant {
00135 from_helper( const QList<T> & l ) {
00136 QList<QVariant> result;
00137 for ( typename QList<T>::const_iterator it = l.begin(), end = l.end() ; it != end ; ++it )
00138 result.push_back( from( *it ) );
00139 QVariant::operator=( result );
00140 }
00141 };
00142 template <> struct from_helper<KUrl::List> : public from_helper< QList<KUrl> > {
00143 from_helper( const KUrl::List & l ) : from_helper< QList<KUrl> >( l ) {}
00144 };
00145
00146 class ChiasmusConfigEntry : public Kleo::CryptoConfigEntry {
00147 unsigned int mIdx;
00148 QVariant mValue;
00149 bool mDirty;
00150 public:
00151 ChiasmusConfigEntry( unsigned int i )
00152 : Kleo::CryptoConfigEntry(),
00153 mIdx( i ), mValue( defaultValue() ), mDirty( false )
00154 {
00155 assert( i < kleo_chiasmus_config_entries_dim );
00156 }
00157 QString name() const { return kleo_chiasmus_config_entries[mIdx].name; }
00158 QString description() const { return i18n( kleo_chiasmus_config_entries[mIdx].description ); }
00159 QString path() const { return name(); }
00160 bool isOptional() const { return kleo_chiasmus_config_entries[mIdx].is_optional; }
00161 bool isReadOnly() const { return false; }
00162 bool isList() const { return kleo_chiasmus_config_entries[mIdx].is_list; }
00163 bool isRuntime() const { return kleo_chiasmus_config_entries[mIdx].is_runtime; }
00164 Level level() const { return static_cast<Level>( kleo_chiasmus_config_entries[mIdx].level ); }
00165 ArgType argType() const { return static_cast<ArgType>( kleo_chiasmus_config_entries[mIdx].type ); }
00166 bool isSet() const { return mValue != defaultValue(); }
00167 bool boolValue() const { return mValue.toBool(); }
00168 QString stringValue() const { return mValue.toString(); }
00169 int intValue() const { return mValue.toInt(); }
00170 unsigned int uintValue() const { return mValue.toUInt(); }
00171 KUrl urlValue() const {
00172 if ( argType() != ArgType_Path && argType() != ArgType_DirPath ) return KUrl( mValue.toString() );
00173 KUrl u; u.setPath( mValue.toString() ); return u;
00174 }
00175 unsigned int numberOfTimesSet() const { return 0; }
00176 QStringList stringValueList() const { return mValue.toStringList(); }
00177 QList<int> intValueList() const { return to< QList<int> >( mValue ); }
00178 QList<unsigned int> uintValueList() const { return to< QList<unsigned int> >( mValue ); }
00179 KUrl::List urlValueList() const {
00180 if ( argType() != ArgType_Path && argType()!= ArgType_DirPath ) return mValue.toStringList();
00181 else return to<KUrl::List>( mValue ); }
00182 void resetToDefault() { mValue = defaultValue(); mDirty = false; }
00183 void setBoolValue( bool value ) { setValue( QVariant( value ) ); }
00184 void setStringValue( const QString & value ) { setValue( value ); }
00185 void setIntValue( int value ) { setValue( value ); }
00186 void setUIntValue( unsigned int value ) { setValue( value ); }
00187 void setURLValue( const KUrl & value ) {
00188 if ( argType() != ArgType_Path && argType()!= ArgType_DirPath ) setValue( value.url() );
00189 else setValue( value.path() );
00190 }
00191 void setNumberOfTimesSet( unsigned int ) {}
00192 void setStringValueList( const QStringList & value ) { setValue( value ); }
00193 void setIntValueList( const QList<int> & l ) { setValue( from( l ) ); }
00194 void setUIntValueList( const QList<unsigned int> & l ) { setValue( from( l ) ); }
00195 void setURLValueList( const KUrl::List & l ) { setValue( from( l ) ); }
00196 bool isDirty() const { return mDirty; }
00197
00198 QVariant value() const { return mValue; }
00199
00200 void sync( KConfigGroup config ) {
00201 if ( !mDirty )
00202 return;
00203 mDirty = false;
00204 config.writeEntry( kleo_chiasmus_config_entries[mIdx].name, mValue );
00205 }
00206 void read( const KConfigGroup & config ) {
00207 mDirty = false;
00208 mValue = config.readEntry( kleo_chiasmus_config_entries[mIdx].name, defaultValue() );
00209 }
00210 private:
00211 QVariant defaultValue() const;
00212 void setValue( const QVariant & value ) { mValue = value; mDirty = true; }
00213 };
00214
00215 QVariant ChiasmusConfigEntry::defaultValue() const {
00216 const kleo_chiasmus_config_data & data = kleo_chiasmus_config_entries[mIdx];
00217 switch ( data.type ) {
00218 default:
00219 return QVariant();
00220 case ArgType_None:
00221 if ( isList() )
00222 return QList<QVariant>() << QVariant( data.defaults.boolean.value );
00223 else
00224 return QVariant( data.defaults.boolean.value );
00225 case ArgType_String:
00226 if ( isList() )
00227 return QStringList( QString::fromLatin1( data.defaults.string ) );
00228 else
00229 return QString::fromLatin1( data.defaults.string );
00230 case ArgType_Int:
00231 if ( isList() )
00232 return QList<QVariant>() << data.defaults.integer;
00233 else
00234 return data.defaults.integer;
00235 case ArgType_UInt:
00236 if ( isList() )
00237 return QList<QVariant>() << data.defaults.unsigned_integer;
00238 else
00239 return data.defaults.unsigned_integer;
00240 case ArgType_Path:
00241 case ArgType_DirPath:
00242 if ( isList() )
00243 return QList<QVariant>() << QString::fromLatin1( data.defaults.path );
00244 else
00245 return QString::fromLatin1( data.defaults.path );
00246 case ArgType_URL:
00247 case ArgType_LDAPURL:
00248 if ( isList() )
00249 return QList<QVariant>() << QString::fromLatin1( data.defaults.url );
00250 else
00251 return QString::fromLatin1( data.defaults.url );
00252 }
00253 }
00254
00255 class ChiasmusGeneralGroup : public Kleo::CryptoConfigGroup {
00256 mutable std::map<QString,ChiasmusConfigEntry*> mCache;
00257 mutable KConfig * mConfigObject;
00258 public:
00259 ChiasmusGeneralGroup() : Kleo::CryptoConfigGroup(), mConfigObject( 0 ) {}
00260 ~ChiasmusGeneralGroup() { clear(); delete mConfigObject; }
00261 QString name() const { return "General"; }
00262 QString iconName() const { return "chiasmus_chi"; }
00263 QString path() const { return QString(); }
00264 QString description() const { return i18n( "General" ); }
00265 Kleo::CryptoConfigEntry::Level level() const { return Kleo::CryptoConfigEntry::Level_Basic; }
00266 QStringList entryList() const {
00267 QStringList result;
00268 for ( unsigned int i = 0 ; i < kleo_chiasmus_config_entries_dim ; ++i )
00269 result.push_back( kleo_chiasmus_config_entries[i].name );
00270 return result;
00271 }
00272 Kleo::CryptoConfigEntry * entry( const QString & name ) const {
00273 if ( ChiasmusConfigEntry * entry = mCache[name] )
00274 return entry;
00275 const KConfigGroup group( configObject(), "Chiasmus" );
00276 for ( unsigned int i = 0 ; i < kleo_chiasmus_config_entries_dim ; ++i )
00277 if ( name == kleo_chiasmus_config_entries[i].name ) {
00278 ChiasmusConfigEntry * entry = new ChiasmusConfigEntry( i );
00279 entry->read( group );
00280 return mCache[name] = entry;
00281 }
00282 return 0;
00283 }
00284
00285 void sync() {
00286 KConfigGroup group( configObject(), "Chiasmus" );
00287 for ( std::map<QString,ChiasmusConfigEntry*>::const_iterator it = mCache.begin(), end = mCache.end() ; it != end ; ++it )
00288 it->second->sync( group );
00289 group.sync();
00290 clear();
00291 }
00292 private:
00293 KConfig * configObject() const {
00294 if ( !mConfigObject )
00295
00296 mConfigObject = new KConfig( "chiasmusbackendrc" );
00297 return mConfigObject;
00298 }
00299 void clear() {
00300 for ( std::map<QString,ChiasmusConfigEntry*>::const_iterator it = mCache.begin(), end = mCache.end() ; it != end ; ++it )
00301 delete it->second;
00302 mCache.clear();
00303 }
00304 };
00305
00306 class ChiasmusComponent : public Kleo::CryptoConfigComponent {
00307 mutable ChiasmusGeneralGroup * mGeneralGroup;
00308 public:
00309 ChiasmusComponent() : Kleo::CryptoConfigComponent(), mGeneralGroup( 0 ) {}
00310 ~ChiasmusComponent() { delete mGeneralGroup; }
00311
00312 void sync() {
00313 if ( mGeneralGroup )
00314 mGeneralGroup->sync();
00315 }
00316
00317 QString name() const { return "Chiasmus"; }
00318 QString iconName() const { return "chiasmus_chi"; }
00319 QString description() const { return i18n( "Chiasmus" ); }
00320 QStringList groupList() const { return QStringList() << "General"; }
00321 Kleo::CryptoConfigGroup * group( const QString & name ) const {
00322 if ( name != "General" )
00323 return 0;
00324 if ( !mGeneralGroup )
00325 mGeneralGroup = new ChiasmusGeneralGroup();
00326 return mGeneralGroup;
00327 }
00328 };
00329
00330 }
00331
00332 class Kleo::ChiasmusBackend::CryptoConfig : public Kleo::CryptoConfig {
00333 mutable ChiasmusComponent * mComponent;
00334 public:
00335 CryptoConfig() : Kleo::CryptoConfig(), mComponent( 0 ) {}
00336 ~CryptoConfig() { delete mComponent; }
00337
00338 QStringList componentList() const { return QStringList() << "Chiasmus" ; }
00339 ChiasmusComponent * component( const QString & name ) const {
00340 if ( name != "Chiasmus" )
00341 return 0;
00342 if ( !mComponent )
00343 mComponent = new ChiasmusComponent();
00344 return mComponent;
00345 }
00346 void sync( bool ) {
00347 if ( mComponent )
00348 mComponent->sync();
00349 }
00350 void clear() { delete mComponent; mComponent = 0; }
00351 };
00352
00353 class Kleo::ChiasmusBackend::Protocol : public Kleo::CryptoBackend::Protocol {
00354 Kleo::CryptoConfig * mCryptoConfig;
00355 public:
00356 Protocol( Kleo::CryptoConfig * config )
00357 : Kleo::CryptoBackend::Protocol(), mCryptoConfig( config )
00358 {
00359 assert( config );
00360 }
00361 ~Protocol() {}
00362
00363 QString name() const { return "Chiasmus"; }
00364 QString displayName() const { return i18n( "Chiasmus command line tool" ); }
00365 KeyListJob * keyListJob( bool, bool, bool ) const { return 0; }
00366 EncryptJob * encryptJob( bool, bool ) const { return 0; }
00367 DecryptJob * decryptJob() const { return 0; }
00368 SignJob * signJob( bool, bool ) const { return 0; }
00369 VerifyDetachedJob * verifyDetachedJob( bool ) const { return 0; }
00370 VerifyOpaqueJob * verifyOpaqueJob( bool ) const { return 0; }
00371 KeyGenerationJob * keyGenerationJob() const { return 0; }
00372 ImportJob * importJob() const { return 0; }
00373 ExportJob * publicKeyExportJob( bool ) const { return 0; }
00374 ExportJob * secretKeyExportJob( bool, const QString& ) const { return 0; }
00375 DownloadJob * downloadJob( bool ) const { return 0; }
00376 DeleteJob * deleteJob() const { return 0; }
00377 SignEncryptJob * signEncryptJob( bool, bool ) const { return 0; }
00378 DecryptVerifyJob * decryptVerifyJob( bool ) const { return 0; }
00379 RefreshKeysJob * refreshKeysJob() const { return 0; }
00380
00381 SpecialJob * specialJob( const char * type, const QMap<QString,QVariant> & args ) const {
00382 if ( qstricmp( type, "x-obtain-keys" ) == 0 && args.size() == 0 )
00383 return new ObtainKeysJob();
00384 if ( qstricmp( type, "x-encrypt" ) == 0 && args.size() == 0 )
00385 return new ChiasmusJob( ChiasmusJob::Encrypt );
00386 if ( qstricmp( type, "x-decrypt" ) == 0 && args.size() == 0 )
00387 return new ChiasmusJob( ChiasmusJob::Decrypt );
00388 kDebug(5150) <<"ChiasmusBackend::Protocol: tried to instantiate unknown job type \""
00389 << type << "\"";
00390
00391 return 0;
00392 }
00393 };
00394
00395 Kleo::ChiasmusBackend * Kleo::ChiasmusBackend::self = 0;
00396
00397 Kleo::ChiasmusBackend::ChiasmusBackend()
00398 : Kleo::CryptoBackend(),
00399 mCryptoConfig( 0 ),
00400 mProtocol( 0 )
00401 {
00402 self = this;
00403 }
00404
00405 Kleo::ChiasmusBackend::~ChiasmusBackend() {
00406 self = 0;
00407 delete mCryptoConfig;
00408 delete mProtocol;
00409 }
00410
00411 QString Kleo::ChiasmusBackend::name() const {
00412 return "Chiasmus";
00413 }
00414
00415 QString Kleo::ChiasmusBackend::displayName() const {
00416 return i18n( "Chiasmus" );
00417 }
00418
00419 Kleo::CryptoConfig * Kleo::ChiasmusBackend::config() const {
00420 if ( !mCryptoConfig )
00421 mCryptoConfig = new CryptoConfig();
00422 return mCryptoConfig;
00423 }
00424
00425 Kleo::CryptoBackend::Protocol * Kleo::ChiasmusBackend::protocol( const char * name ) const {
00426 if ( qstricmp( name, "Chiasmus" ) != 0 )
00427 return 0;
00428 if ( !mProtocol )
00429 if ( checkForChiasmus() )
00430 mProtocol = new Protocol( config() );
00431 return mProtocol;
00432 }
00433
00434 bool Kleo::ChiasmusBackend::checkForOpenPGP( QString * reason ) const {
00435 if ( reason )
00436 *reason = i18n( "Unsupported protocol \"%1\"", QString("OpenPGP") );
00437 return false;
00438 }
00439
00440 bool Kleo::ChiasmusBackend::checkForSMIME( QString * reason ) const {
00441 if ( reason )
00442 *reason = i18n( "Unsupported protocol \"%1\"", QString("SMIME") );
00443 return false;
00444 }
00445
00446 bool Kleo::ChiasmusBackend::checkForChiasmus( QString * reason ) const {
00447
00448
00449 std::auto_ptr<Protocol> tmp( mProtocol );
00450 mProtocol = 0;
00451
00452 const CryptoConfigEntry * path = config()->entry( "Chiasmus", "General", "path" );
00453 assert( path ); assert( path->argType() == CryptoConfigEntry::ArgType_Path );
00454 const QString chiasmus = path->urlValue().path();
00455 const QFileInfo fi( KShell::tildeExpand( chiasmus ) );
00456 if ( !fi.isExecutable() ) {
00457 if ( reason )
00458 *reason = i18n( "File \"%1\" does not exist or is not executable.", chiasmus );
00459 return false;
00460 }
00461
00462
00463 mProtocol = tmp.release();
00464 return true;
00465 }
00466
00467 bool Kleo::ChiasmusBackend::checkForProtocol( const char * name, QString * reason ) const {
00468 if ( qstricmp( name, "Chiasmus" ) == 0 )
00469 return checkForChiasmus( reason );
00470 if ( reason )
00471 *reason = i18n( "Unsupported protocol \"%1\"", name );
00472 return 0;
00473 }
00474
00475 bool Kleo::ChiasmusBackend::supportsProtocol( const char * name ) const {
00476 return qstricmp( name, "Chiasmus" ) == 0;
00477 }
00478
00479 const char * Kleo::ChiasmusBackend::enumerateProtocols( int i ) const {
00480 return i == 0 ? "Chiasmus" : 0 ;
00481 }