libkleo
cryptobackendfactory.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 "cryptobackendfactory.h"
00034
00035 #include "libkleo/backends/qgpgme/qgpgmebackend.h"
00036 #if 0 // disabled for kde-3.3
00037 #include "libkleo/backends/kpgp/pgp2backend.h"
00038 #include "libkleo/backends/kpgp/pgp5backend.h"
00039 #include "libkleo/backends/kpgp/pgp6backend.h"
00040 #include "libkleo/backends/kpgp/gpg1backend.h"
00041 #endif
00042
00043 #ifndef ONLY_KLEO
00044 # include "libkleo/backends/chiasmus/chiasmusbackend.h"
00045 # include "libkleo/ui/backendconfigwidget.h"
00046 #endif
00047
00048 #include <kconfig.h>
00049 #include <klocale.h>
00050 #include <kdebug.h>
00051 #include <kmessagebox.h>
00052 #include <kconfiggroup.h>
00053
00054 #include <QApplication>
00055 #include <iterator>
00056 #include <algorithm>
00057
00058 #include <cassert>
00059
00060 Kleo::CryptoBackendFactory * Kleo::CryptoBackendFactory::mSelf = 0;
00061
00062 static const char * availableProtocols[] = {
00063 #ifndef ONLY_KLEO
00064 "Chiasmus",
00065 #endif
00066 "OpenPGP", "SMIME",
00067 };
00068 static const unsigned int numAvailableProtocols = sizeof availableProtocols / sizeof *availableProtocols;
00069
00070 Kleo::CryptoBackendFactory::CryptoBackendFactory()
00071 : QObject( qApp ),
00072 mConfigObject( 0 ),
00073 mAvailableProtocols( availableProtocols, availableProtocols + numAvailableProtocols )
00074 {
00075 setObjectName("CryptoBackendFactory::instance()");
00076 mBackendList.push_back( new QGpgMEBackend() );
00077 #if 0 // disabled for kde-3.3
00078 mBackendList.push_back( new PGP2Backend() );
00079 mBackendList.push_back( new PGP5Backend() );
00080 mBackendList.push_back( new PGP6Backend() );
00081 mBackendList.push_back( new GPG1Backend() );
00082 #endif
00083 #ifndef ONLY_KLEO
00084 mBackendList.push_back( new ChiasmusBackend() );
00085 #endif
00086 scanForBackends();
00087 readConfig();
00088
00089 mSelf = this;
00090 }
00091
00092 Kleo::CryptoBackendFactory::~CryptoBackendFactory() {
00093 mSelf = 0;
00094
00095 for ( std::vector<CryptoBackend*>::iterator it = mBackendList.begin() ; it != mBackendList.end() ; ++it ) {
00096 delete *it;
00097 *it = 0;
00098 }
00099 delete mConfigObject;
00100 mConfigObject = 0;
00101 }
00102
00103 Kleo::CryptoBackendFactory * Kleo::CryptoBackendFactory::instance() {
00104 if ( !mSelf )
00105 mSelf = new CryptoBackendFactory();
00106 return mSelf;
00107 }
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 const Kleo::CryptoBackend::Protocol * Kleo::CryptoBackendFactory::smime() const {
00119 const BackendMap::const_iterator it = mBackends.find( "SMIME" );
00120 if ( it == mBackends.end() )
00121 return 0;
00122 if ( !it->second )
00123 return 0;
00124 return it->second->smime();
00125 }
00126
00127 const Kleo::CryptoBackend::Protocol * Kleo::CryptoBackendFactory::openpgp() const {
00128 const BackendMap::const_iterator it = mBackends.find( "OpenPGP" );
00129 if ( it == mBackends.end() )
00130 return 0;
00131 if ( !it->second )
00132 return 0;
00133 return it->second->openpgp();
00134 }
00135
00136 const Kleo::CryptoBackend::Protocol * Kleo::CryptoBackendFactory::protocol( const char * name ) const {
00137 const BackendMap::const_iterator it = mBackends.find( name );
00138 if ( it == mBackends.end() )
00139 return 0;
00140 if ( !it->second )
00141 return 0;
00142 return it->second->protocol( name );
00143 }
00144
00145 const Kleo::CryptoBackend::Protocol * Kleo::CryptoBackendFactory::protocol( GpgME::Protocol proto ) const {
00146 if ( proto == GpgME::OpenPGP )
00147 return openpgp();
00148 else if ( proto == GpgME::CMS )
00149 return smime();
00150 else
00151 return 0;
00152 }
00153
00154 Kleo::CryptoConfig * Kleo::CryptoBackendFactory::config() const {
00155
00156 return backend( 0 ) ? backend( 0 )->config() : 0;
00157 }
00158
00159 bool Kleo::CryptoBackendFactory::hasBackends() const {
00160 return !mBackendList.empty();
00161 }
00162
00163 void Kleo::CryptoBackendFactory::scanForBackends( QStringList * reasons ) {
00164 for ( std::vector<CryptoBackend*>::const_iterator it = mBackendList.begin() ; it != mBackendList.end() ; ++it ) {
00165 assert( *it );
00166 for ( int i = 0 ;; ++i ) {
00167 const char * protocol = (*it)->enumerateProtocols( i );
00168 if ( !protocol )
00169 break;
00170 QString reason;
00171 if ( (*it)->supportsProtocol( protocol ) && !(*it)->checkForProtocol( protocol, &reason ) ) {
00172 if ( reasons ) {
00173 reasons->push_back( i18n("While scanning for %1 support in backend %2:",
00174 protocol, (*it)->displayName() ) );
00175 reasons->push_back( " " + reason );
00176 }
00177 }
00178 }
00179 }
00180 }
00181
00182 const Kleo::CryptoBackend * Kleo::CryptoBackendFactory::backend( unsigned int idx ) const {
00183 return ( idx < mBackendList.size() ) ? mBackendList[idx] : 0 ;
00184 }
00185
00186 const Kleo::CryptoBackend * Kleo::CryptoBackendFactory::backendByName( const QString& name ) const {
00187 for ( std::vector<CryptoBackend*>::const_iterator it = mBackendList.begin() ; it != mBackendList.end() ; ++it ) {
00188 if ( (*it)->name() == name )
00189 return *it;
00190 }
00191 return 0;
00192 }
00193
00194 Kleo::BackendConfigWidget * Kleo::CryptoBackendFactory::configWidget( QWidget * parent, const char * name ) const {
00195 #ifndef ONLY_KLEO
00196 return new Kleo::BackendConfigWidget( mSelf, parent, name );
00197 #else
00198 return 0;
00199 #endif
00200 }
00201
00202 KConfig* Kleo::CryptoBackendFactory::configObject() const {
00203 if ( !mConfigObject )
00204
00205 mConfigObject = new KConfig( "libkleopatrarc" );
00206 return mConfigObject;
00207 }
00208
00209 void Kleo::CryptoBackendFactory::setSMIMEBackend( const CryptoBackend* backend ) {
00210 setProtocolBackend( "SMIME", backend );
00211 }
00212
00213 void Kleo::CryptoBackendFactory::setOpenPGPBackend( const CryptoBackend* backend ) {
00214 setProtocolBackend( "OpenPGP", backend );
00215 }
00216
00217 void Kleo::CryptoBackendFactory::setProtocolBackend( const char * protocol, const CryptoBackend * backend ) {
00218 const QString name = backend ? backend->name() : QString() ;
00219 KConfigGroup group( configObject(), "Backends" );
00220 group.writeEntry( protocol, name );
00221 configObject()->sync();
00222 mBackends[protocol] = backend;
00223 }
00224
00225 static const char * defaultBackend( const char * proto ) {
00226 static const struct {
00227 const char * proto;
00228 const char * backend;
00229 } defaults[] = {
00230 { "OpenPGP", "gpgme" },
00231 { "SMIME", "gpgme" },
00232 #ifndef ONLY_KLEO
00233 { "Chiasmus", "chiasmus" },
00234 #endif
00235 };
00236 for ( unsigned int i = 0 ; i < sizeof defaults / sizeof *defaults ; ++i )
00237 if ( qstricmp( proto, defaults[i].proto ) == 0 )
00238 return defaults[i].backend;
00239 return 0;
00240 }
00241
00242 void Kleo::CryptoBackendFactory::readConfig() {
00243 mBackends.clear();
00244 const KConfigGroup group( configObject(), "Backends" );
00245 for ( ProtocolSet::const_iterator it = mAvailableProtocols.begin(), end = mAvailableProtocols.end() ; it != end ; ++it ) {
00246 const QString backend = group.readEntry( *it, defaultBackend( *it ) );
00247 mBackends[*it] = backendByName( backend );
00248 }
00249 }
00250
00251 const char * Kleo::CryptoBackendFactory::enumerateProtocols( int i ) const {
00252 if ( i < 0 || static_cast<unsigned int>( i ) >= mAvailableProtocols.size() )
00253 return 0;
00254 return mAvailableProtocols[i];
00255 }
00256
00257 namespace {
00258 class CaseInsensitiveString {
00259 const char * m;
00260 public:
00261 CaseInsensitiveString( const char * s ) : m( s ) {}
00262 #define make_operator( op ) \
00263 bool operator op( const CaseInsensitiveString & other ) const { \
00264 return qstricmp( m, other.m ) op 0; \
00265 } \
00266 bool operator op( const char * other ) const { \
00267 return qstricmp( m, other ) op 0; \
00268 }
00269 make_operator( == )
00270 make_operator( != )
00271 make_operator( < )
00272 make_operator( > )
00273 make_operator( <= )
00274 make_operator( >= )
00275 #undef make_operator
00276 operator const char *() const { return m; }
00277 };
00278 #define make_ext_operator( op, inv_op ) \
00279 inline bool operator op( const char * lhs, const CaseInsensitiveString & rhs ) { \
00280 return rhs.operator inv_op( lhs ); \
00281 }
00282 make_ext_operator( ==, == )
00283 make_ext_operator( !=, != )
00284 make_ext_operator( <, > )
00285 make_ext_operator( >, < )
00286 make_ext_operator( <=, >= )
00287 make_ext_operator( >=, <= )
00288 #undef make_ext_operator
00289
00290 }
00291
00292 bool Kleo::CryptoBackendFactory::knowsAboutProtocol( const char * name ) const {
00293 return std::find( mAvailableProtocols.begin(), mAvailableProtocols.end(),
00294 CaseInsensitiveString( name ) ) != mAvailableProtocols.end();
00295 }
00296
00297 #include "cryptobackendfactory.moc"