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