certmanager Library API Documentation

chiasmusbackend.cpp

00001 /*
00002     chiasmusbackend.cpp
00003 
00004     This file is part of libkleopatra, the KDE keymanagement library
00005     Copyright (c) 2005 Klarälvdalens Datakonsult AB
00006 
00007     Libkleopatra is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU General Public License as
00009     published by the Free Software Foundation; either version 2 of the
00010     License, or (at your option) any later version.
00011 
00012     Libkleopatra is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     General Public License for more details.
00016 
00017     You should have received a copy of the GNU General Public License
00018     along with this program; if not, write to the Free Software
00019     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 
00021     In addition, as a special exception, the copyright holders give
00022     permission to link the code of this program with any edition of
00023     the Qt library by Trolltech AS, Norway (or with modified versions
00024     of Qt that use the same license as Qt), and distribute linked
00025     combinations including the two.  You must obey the GNU General
00026     Public License in all respects for all of the code used other than
00027     Qt.  If you modify this file, you may extend this exception to
00028     your version of the file, but you are not obligated to do so.  If
00029     you do not wish to do so, delete this exception statement from
00030     your version.
00031 */
00032 
00033 #ifdef HAVE_CONFIG_H
00034 #include <config.h>
00035 #endif
00036 
00037 #include "chiasmusbackend.h"
00038 
00039 #include "config_data.h"
00040 #include "obtainkeysjob.h"
00041 #include "chiasmusjob.h"
00042 
00043 #include "kleo/cryptoconfig.h"
00044 
00045 #include <klocale.h>
00046 #include <kconfig.h>
00047 #include <kshell.h>
00048 #include <kdebug.h>
00049 
00050 #include <qstringlist.h>
00051 #include <qvariant.h>
00052 #include <qfileinfo.h>
00053 
00054 #include <map>
00055 #include <memory>
00056 
00057 #include <cassert>
00058 
00059 namespace {
00060 
00061   //
00062   // The usual QVariant template helpers:
00063   //
00064 
00065   // to<> is a demarshaller. It's a class b/c you can't partially
00066   // specialise function templates yet. However, to<> can be used as if
00067   // it was a function: QString s = to<QString>( myVariant );
00068   template <typename T> class to {};
00069 
00070 #define MAKE_TO( type, func ) \
00071   template <> \
00072   class to< type > { \
00073     type m; \
00074   public: \
00075     to( const QVariant & v ) : m( v.func() ) {} \
00076     operator type() const { return m; } \
00077   }
00078 
00079   MAKE_TO( int, toInt );
00080   MAKE_TO( unsigned int, toUInt );
00081 
00082   template <>
00083   class to<KURL> {
00084     KURL m;
00085   public:
00086     to( const QVariant & v ) {
00087       m.setPath( v.toString() );
00088     }
00089     operator KURL() const { return m; }
00090   };
00091 
00092   template <typename T>
00093   class to< QValueList<T> > {
00094     QValueList<T> m;
00095   public:
00096     to( const QVariant & v ) {
00097       const QValueList<QVariant> vl = v.toList();
00098       for ( QValueList<QVariant>::const_iterator it = vl.begin(), end = vl.end() ; it != end ; ++it )
00099         m.push_back( to<T>( *it ) );
00100     }
00101     operator QValueList<T> () const { return m; }
00102   };
00103 
00104   template <>
00105   class to<KURL::List> {
00106     KURL::List m;
00107   public:
00108     to( const QVariant & v ) {
00109       // wow, KURL::List is broken... it lacks conversion from and to QVL<KURL>...
00110       m += to< QValueList<KURL> >( v );
00111     }
00112     operator KURL::List() const { return m; }
00113   };
00114 
00115 
00116   // from<> is the demarshaller. See to<> for why this is a class...
00117 
00118   template <typename T>
00119   struct from_helper : public QVariant {
00120     from_helper( const T & t ) : QVariant( t ) {}
00121   };
00122 
00123   template <typename T>
00124   QVariant from( const T & t ) {
00125     return from_helper<T>( t );
00126   }
00127 
00128   // some special types:
00129   template <> struct from_helper<bool> : public QVariant {
00130     from_helper( bool b ) : QVariant( b, int() ) {}
00131   };
00132   template <> struct from_helper<KURL> : public QVariant {
00133     from_helper( const KURL & url ) : QVariant( url.path() ) {}
00134   };
00135   template <typename T> struct from_helper< QValueList<T> > : public QVariant {
00136     from_helper( const QValueList<T> & l ) {
00137       QValueList<QVariant> result;
00138       for ( typename QValueList<T>::const_iterator it = l.begin(), end = l.end() ; it != end ; ++it )
00139         result.push_back( from( *it ) );
00140       QVariant::operator=( result );
00141     }
00142   };
00143   template <> struct from_helper<KURL::List> : public from_helper< QValueList<KURL> > {
00144     from_helper( const KURL::List & l ) : from_helper< QValueList<KURL> >( l ) {}
00145   };
00146 
00147   class ChiasmusConfigEntry : public Kleo::CryptoConfigEntry {
00148     unsigned int mIdx;
00149     QVariant mValue;
00150     bool mDirty;
00151   public:
00152     ChiasmusConfigEntry( unsigned int i )
00153       : Kleo::CryptoConfigEntry(),
00154         mIdx( i ), mValue( defaultValue() ), mDirty( false )
00155     {
00156       assert( i < kleo_chiasmus_config_entries_dim );
00157     }
00158     QString name() const { return kleo_chiasmus_config_entries[mIdx].name; }
00159     QString description() const { return i18n( kleo_chiasmus_config_entries[mIdx].description ); }
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     QValueList<int> intValueList() const { return to< QValueList<int> >( mValue ); }
00178     QValueList<unsigned int> uintValueList() const { return to< QValueList<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, int() ) ); }
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 QValueList<int> & l ) { setValue( from( l ) ); }
00194     void setUIntValueList( const QValueList<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( KConfigBase * config ) {
00201       if ( !mDirty )
00202         return;
00203       mDirty = false;
00204       config->writeEntry( kleo_chiasmus_config_entries[mIdx].name, mValue );
00205     }
00206     void read( const KConfigBase * config ) {
00207       mDirty = false;
00208       mValue = config->readPropertyEntry( 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 QValueList<QVariant>() << QVariant( data.defaults.boolean.value, int() );
00223       else
00224         return QVariant( data.defaults.boolean.value, int() );
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 QValueList<QVariant>() << data.defaults.integer;
00233       else
00234         return data.defaults.integer;
00235     case ArgType_UInt:
00236       if ( isList() )
00237         return QValueList<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 QValueList<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 QValueList<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 description() const { return i18n( "General" ); }
00264     Kleo::CryptoConfigEntry::Level level() const { return Kleo::CryptoConfigEntry::Level_Basic; }
00265     QStringList entryList() const {
00266       QStringList result;
00267       for ( unsigned int i = 0 ; i < kleo_chiasmus_config_entries_dim ; ++i )
00268         result.push_back( kleo_chiasmus_config_entries[i].name );
00269       return result;
00270     }
00271     Kleo::CryptoConfigEntry * entry( const QString & name ) const {
00272       if ( ChiasmusConfigEntry * entry = mCache[name] )
00273         return entry;
00274       const KConfigGroup group( configObject(), "Chiasmus" );
00275       for ( unsigned int i = 0 ; i < kleo_chiasmus_config_entries_dim ; ++i )
00276         if ( name == kleo_chiasmus_config_entries[i].name ) {
00277           ChiasmusConfigEntry * entry = new ChiasmusConfigEntry( i );
00278           entry->read( &group );
00279           return mCache[name] = entry;
00280         }
00281       return 0;
00282     }
00283 
00284     void sync() {
00285       KConfigGroup group( configObject(), "Chiasmus" );
00286       for ( std::map<QString,ChiasmusConfigEntry*>::const_iterator it = mCache.begin(), end = mCache.end() ; it != end ; ++it )
00287         it->second->sync( &group );
00288       group.sync();
00289       clear();
00290     }
00291   private:
00292     KConfig * configObject() const {
00293       if ( !mConfigObject )
00294         // this is unsafe. We're a lib, used by concurrent apps.
00295         mConfigObject = new KConfig( "chiasmusbackendrc" );
00296       return mConfigObject;
00297     }
00298     void clear() {
00299       for ( std::map<QString,ChiasmusConfigEntry*>::const_iterator it = mCache.begin(), end = mCache.end() ; it != end ; ++it )
00300         delete it->second;
00301       mCache.clear();
00302     }
00303   };
00304 
00305   class ChiasmusComponent : public Kleo::CryptoConfigComponent {
00306     mutable ChiasmusGeneralGroup * mGeneralGroup;
00307   public:
00308     ChiasmusComponent() : Kleo::CryptoConfigComponent(), mGeneralGroup( 0 ) {}
00309     ~ChiasmusComponent() { delete mGeneralGroup; }
00310 
00311     void sync() {
00312       if ( mGeneralGroup )
00313         mGeneralGroup->sync();
00314     }
00315 
00316     QString name() const { return "Chiasmus"; }
00317     QString iconName() const { return "chiasmus_chi"; }
00318     QString description() const { return i18n( "Chiasmus" ); }
00319     QStringList groupList() const { return QStringList() << "General"; }
00320     Kleo::CryptoConfigGroup * group( const QString & name ) const {
00321       if ( name != "General" )
00322         return 0;
00323       if ( !mGeneralGroup )
00324         mGeneralGroup = new ChiasmusGeneralGroup();
00325       return mGeneralGroup;
00326     }
00327   };
00328 
00329 }
00330 
00331 class Kleo::ChiasmusBackend::CryptoConfig : public Kleo::CryptoConfig {
00332   mutable ChiasmusComponent * mComponent;
00333 public:
00334   CryptoConfig() : Kleo::CryptoConfig(), mComponent( 0 ) {}
00335   ~CryptoConfig() { delete mComponent; }
00336 
00337   QStringList componentList() const { return QStringList() << "Chiasmus" ; }
00338   ChiasmusComponent * component( const QString & name ) const {
00339     if ( name != "Chiasmus" )
00340       return 0;
00341     if ( !mComponent )
00342       mComponent = new ChiasmusComponent();
00343     return mComponent;
00344   }
00345   void sync( bool ) {
00346     if ( mComponent )
00347       mComponent->sync();
00348   }
00349   void clear() { delete mComponent; mComponent = 0; }
00350 };
00351 
00352 class Kleo::ChiasmusBackend::Protocol : public Kleo::CryptoBackend::Protocol {
00353   Kleo::CryptoConfig * mCryptoConfig;
00354 public:
00355   Protocol( Kleo::CryptoConfig * config )
00356     : Kleo::CryptoBackend::Protocol(), mCryptoConfig( config )
00357   {
00358     assert( config );
00359   }
00360   ~Protocol() {}
00361 
00362   QString name() const { return "Chiasmus"; }
00363   QString displayName() const { return i18n( "Chiasmus command line tool" ); }
00364   KeyListJob * keyListJob( bool, bool, bool ) const { return 0; }
00365   EncryptJob * encryptJob( bool, bool ) const { return 0; }
00366   DecryptJob * decryptJob() const { return 0; }
00367   SignJob * signJob( bool, bool ) const { return 0; }
00368   VerifyDetachedJob * verifyDetachedJob( bool ) const { return 0; }
00369   VerifyOpaqueJob * verifyOpaqueJob( bool ) const { return 0; }
00370   KeyGenerationJob * keyGenerationJob() const { return 0; }
00371   ImportJob * importJob() const { return 0; }
00372   ExportJob * publicKeyExportJob( bool ) const { return 0; }
00373   ExportJob * secretKeyExportJob( bool, const QString& ) const { return 0; }
00374   DownloadJob * downloadJob( bool ) const { return 0; }
00375   DeleteJob * deleteJob() const { return 0; }
00376   SignEncryptJob * signEncryptJob( bool, bool ) const { return 0; }
00377   DecryptVerifyJob * decryptVerifyJob( bool ) const { return 0; }
00378   RefreshKeysJob * refreshKeysJob() const { return 0; }
00379 
00380   SpecialJob * specialJob( const char * type, const QMap<QString,QVariant> & args ) const {
00381     if ( qstricmp( type, "x-obtain-keys" ) == 0 && args.size() == 0 )
00382       return new ObtainKeysJob();
00383     if ( qstricmp( type, "x-encrypt" ) == 0 && args.size() == 0 )
00384       return new ChiasmusJob( ChiasmusJob::Encrypt );
00385     if ( qstricmp( type, "x-decrypt" ) == 0 && args.size() == 0 )
00386       return new ChiasmusJob( ChiasmusJob::Decrypt );
00387     kdDebug(5150) << "ChiasmusBackend::Protocol: tried to instantiate unknown job type \""
00388                   << type << "\"" << endl;
00389 
00390     return 0;
00391   }
00392 };
00393 
00394 Kleo::ChiasmusBackend * Kleo::ChiasmusBackend::self = 0;
00395 
00396 Kleo::ChiasmusBackend::ChiasmusBackend()
00397   : Kleo::CryptoBackend(),
00398     mCryptoConfig( 0 ),
00399     mProtocol( 0 )
00400 {
00401   self = this;
00402 }
00403 
00404 Kleo::ChiasmusBackend::~ChiasmusBackend() {
00405   self = 0;
00406   delete mCryptoConfig;
00407   delete mProtocol;
00408 }
00409 
00410 QString Kleo::ChiasmusBackend::name() const {
00411   return "Chiasmus";
00412 }
00413 
00414 QString Kleo::ChiasmusBackend::displayName() const {
00415   return i18n( "Chiasmus" );
00416 }
00417 
00418 Kleo::CryptoConfig * Kleo::ChiasmusBackend::config() const {
00419   if ( !mCryptoConfig )
00420     mCryptoConfig = new CryptoConfig();
00421   return mCryptoConfig;
00422 }
00423 
00424 Kleo::CryptoBackend::Protocol * Kleo::ChiasmusBackend::protocol( const char * name ) const {
00425   if ( qstricmp( name, "Chiasmus" ) != 0 )
00426     return 0;
00427   if ( !mProtocol )
00428     if ( checkForChiasmus() )
00429       mProtocol = new Protocol( config() );
00430   return mProtocol;
00431 }
00432 
00433 bool Kleo::ChiasmusBackend::checkForOpenPGP( QString * reason ) const {
00434   if ( reason )
00435     *reason = i18n( "Unsupported protocol \"%1\"" ).arg( "OpenPGP" );
00436   return false;
00437 }
00438 
00439 bool Kleo::ChiasmusBackend::checkForSMIME( QString * reason ) const {
00440   if ( reason )
00441     *reason = i18n( "Unsupported protocol \"%1\"" ).arg( "SMIME" );
00442   return false;
00443 }
00444 
00445 bool Kleo::ChiasmusBackend::checkForChiasmus( QString * reason ) const {
00446 
00447   // kills the protocol instance when we return false:
00448   std::auto_ptr<Protocol> tmp( mProtocol );
00449   mProtocol = 0;
00450 
00451   const CryptoConfigEntry * path = config()->entry( "Chiasmus", "General", "path" );
00452   assert( path ); assert( path->argType() == CryptoConfigEntry::ArgType_Path );
00453   const QString chiasmus = path->urlValue().path();
00454   const QFileInfo fi( KShell::tildeExpand( chiasmus ) );
00455   if ( !fi.isExecutable() ) {
00456     if ( reason )
00457       *reason = i18n( "File \"%1\" does not exist or is not executable." ).arg( chiasmus );
00458     return false;
00459   }
00460 
00461   // FIXME: more checks?
00462   mProtocol = tmp.release();
00463   return true;
00464 }
00465 
00466 bool Kleo::ChiasmusBackend::checkForProtocol( const char * name, QString * reason ) const {
00467   if ( qstricmp( name, "Chiasmus" ) == 0 )
00468     return checkForChiasmus( reason );
00469   if ( reason )
00470     *reason = i18n( "Unsupported protocol \"%1\"" ).arg( name );
00471   return 0;
00472 }
00473 
00474 bool Kleo::ChiasmusBackend::supportsProtocol( const char * name ) const {
00475   return qstricmp( name, "Chiasmus" ) == 0;
00476 }
00477 
00478 const char * Kleo::ChiasmusBackend::enumerateProtocols( int i ) const {
00479   return i == 0 ? "Chiasmus" : 0 ;
00480 }
KDE Logo
This file is part of the documentation for certmanager Library Version 3.3.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Jul 25 11:17:52 2007 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003