certmanager/lib

cryptobackendfactory.cpp
1/*
2 cryptobackendfactory.cpp
3
4 This file is part of libkleopatra, the KDE key management library
5 Copyright (c) 2001,2004,2005 Klarälvdalens Datakonsult AB
6
7 Libkleopatra is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
11
12 Libkleopatra is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
21 In addition, as a special exception, the copyright holders give
22 permission to link the code of this program with any edition of
23 the TQt library by Trolltech AS, Norway (or with modified versions
24 of TQt that use the same license as TQt), and distribute linked
25 combinations including the two. You must obey the GNU General
26 Public License in all respects for all of the code used other than
27 TQt. If you modify this file, you may extend this exception to
28 your version of the file, but you are not obligated to do so. If
29 you do not wish to do so, delete this exception statement from
30 your version.
31*/
32
33#ifdef HAVE_CONFIG_H
34#include <config.h>
35#endif
36
37#include "cryptobackendfactory.h"
38
39#include <backends/qgpgme/qgpgmebackend.h>
40#if 0 // disabled for kde-3.3
41#include <backends/kpgp/pgp2backend.h>
42#include <backends/kpgp/pgp5backend.h>
43#include <backends/kpgp/pgp6backend.h>
44#include <backends/kpgp/gpg1backend.h>
45#endif
46#include <backends/chiasmus/chiasmusbackend.h>
47#include <ui/backendconfigwidget.h>
48
49#include <tdeconfig.h>
50#include <tdelocale.h>
51#include <kdebug.h>
52#include <tdemessagebox.h>
53#include <tdeapplication.h>
54
55#include <iterator>
56#include <algorithm>
57
58#include <cassert>
59
60Kleo::CryptoBackendFactory * Kleo::CryptoBackendFactory::mSelf = 0;
61
62static const char * availableProtocols[] = {
63 "Chiasmus",
64 "OpenPGP", "SMIME",
65};
66static const unsigned int numAvailableProtocols = sizeof availableProtocols / sizeof *availableProtocols;
67
68Kleo::CryptoBackendFactory::CryptoBackendFactory()
69 : TQObject( tqApp, "CryptoBackendFactory::instance()" ),
70 mConfigObject( 0 ),
71 mAvailableProtocols( availableProtocols, availableProtocols + numAvailableProtocols )
72{
73 mBackendList.push_back( new QGpgMEBackend() );
74#if 0 // disabled for kde-3.3
75 mBackendList.push_back( new PGP2Backend() );
76 mBackendList.push_back( new PGP5Backend() );
77 mBackendList.push_back( new PGP6Backend() );
78 mBackendList.push_back( new GPG1Backend() );
79#endif
80 mBackendList.push_back( new ChiasmusBackend() );
81 scanForBackends();
82 readConfig();
83
84 mSelf = this; // last!
85}
86
87Kleo::CryptoBackendFactory::~CryptoBackendFactory() {
88 mSelf = 0; // first!
89
90 for ( std::vector<CryptoBackend*>::iterator it = mBackendList.begin() ; it != mBackendList.end() ; ++it ) {
91 delete *it;
92 *it = 0;
93 }
94 delete mConfigObject;
95 mConfigObject = 0;
96}
97
98Kleo::CryptoBackendFactory * Kleo::CryptoBackendFactory::instance() {
99 if ( !mSelf )
100 mSelf = new CryptoBackendFactory();
101 return mSelf;
102}
103
104
105// const Kleo::CryptoBackend* Kleo::CryptoBackendFactory::smimeBackend() const {
106// return mSMIMEBackend;
107// }
108
109// const Kleo::CryptoBackend* Kleo::CryptoBackendFactory::openpgpBackend() const {
110// return mOpenPGPBackend;
111// }
112
113const Kleo::CryptoBackend::Protocol * Kleo::CryptoBackendFactory::smime() const {
114 const BackendMap::const_iterator it = mBackends.find( "SMIME" );
115 if ( it == mBackends.end() )
116 return 0;
117 if ( !it->second )
118 return 0;
119 return it->second->smime();
120}
121
122const Kleo::CryptoBackend::Protocol * Kleo::CryptoBackendFactory::openpgp() const {
123 const BackendMap::const_iterator it = mBackends.find( "OpenPGP" );
124 if ( it == mBackends.end() )
125 return 0;
126 if ( !it->second )
127 return 0;
128 return it->second->openpgp();
129}
130
131const Kleo::CryptoBackend::Protocol * Kleo::CryptoBackendFactory::protocol( const char * name ) const {
132 const BackendMap::const_iterator it = mBackends.find( name );
133 if ( it == mBackends.end() )
134 return 0;
135 if ( !it->second )
136 return 0;
137 return it->second->protocol( name );
138}
139
140Kleo::CryptoConfig * Kleo::CryptoBackendFactory::config() const {
141 // ## should we use mSMIMEBackend? mOpenPGPBackend? backend(0) i.e. always qgpgme?
142 return backend( 0 ) ? backend( 0 )->config() : 0;
143}
144
145bool Kleo::CryptoBackendFactory::hasBackends() const {
146 return !mBackendList.empty();
147}
148
149void Kleo::CryptoBackendFactory::scanForBackends( TQStringList * reasons ) {
150 for ( std::vector<CryptoBackend*>::const_iterator it = mBackendList.begin() ; it != mBackendList.end() ; ++it ) {
151 assert( *it );
152 for ( int i = 0 ; const char * protocol = (*it)->enumerateProtocols( i ) ; ++i ) {
153 TQString reason;
154 if ( (*it)->supportsProtocol( protocol ) && !(*it)->checkForProtocol( protocol, &reason ) ) {
155 if ( reasons ) {
156 reasons->push_back( i18n("While scanning for %1 support in backend %2:")
157 .arg( protocol, (*it)->displayName() ) );
158 reasons->push_back( " " + reason );
159 }
160 }
161 }
162 }
163}
164
165const Kleo::CryptoBackend * Kleo::CryptoBackendFactory::backend( unsigned int idx ) const {
166 return ( idx < mBackendList.size() ) ? mBackendList[idx] : 0 ;
167}
168
169const Kleo::CryptoBackend * Kleo::CryptoBackendFactory::backendByName( const TQString& name ) const {
170 for ( std::vector<CryptoBackend*>::const_iterator it = mBackendList.begin() ; it != mBackendList.end() ; ++it ) {
171 if ( (*it)->name() == name )
172 return *it;
173 }
174 return 0;
175}
176
177Kleo::BackendConfigWidget * Kleo::CryptoBackendFactory::configWidget( TQWidget * parent, const char * name ) const {
178 return new Kleo::BackendConfigWidget( mSelf, parent, name );
179}
180
181TDEConfig* Kleo::CryptoBackendFactory::configObject() const {
182 if ( !mConfigObject )
183 // this is unsafe. We're a lib, used by concurrent apps.
184 mConfigObject = new TDEConfig( "libkleopatrarc" );
185 return mConfigObject;
186}
187
188void Kleo::CryptoBackendFactory::setSMIMEBackend( const CryptoBackend* backend ) {
189 setProtocolBackend( "SMIME", backend );
190}
191
192void Kleo::CryptoBackendFactory::setOpenPGPBackend( const CryptoBackend* backend ) {
193 setProtocolBackend( "OpenPGP", backend );
194}
195
196void Kleo::CryptoBackendFactory::setProtocolBackend( const char * protocol, const CryptoBackend * backend ) {
197 const TQString name = backend ? backend->name() : TQString() ;
198 TDEConfigGroup group( configObject(), "Backends" );
199 group.writeEntry( protocol, name );
200 configObject()->sync();
201 mBackends[protocol] = backend;
202}
203
204static const char * defaultBackend( const char * proto ) {
205 static const struct {
206 const char * proto;
207 const char * backend;
208 } defaults[] = {
209 { "OpenPGP", "gpgme" },
210 { "SMIME", "gpgme" },
211 { "Chiasmus", "chiasmus" },
212 };
213 for ( unsigned int i = 0 ; i < sizeof defaults / sizeof *defaults ; ++i )
214 if ( tqstricmp( proto, defaults[i].proto ) == 0 )
215 return defaults[i].backend;
216 return 0;
217}
218
219void Kleo::CryptoBackendFactory::readConfig() {
220 mBackends.clear();
221 const TDEConfigGroup group( configObject(), "Backends" );
222 for ( ProtocolSet::const_iterator it = mAvailableProtocols.begin(), end = mAvailableProtocols.end() ; it != end ; ++it ) {
223 const TQString backend = group.readEntry( *it, defaultBackend( *it ) );
224 mBackends[*it] = backendByName( backend );
225 }
226}
227
228const char * Kleo::CryptoBackendFactory::enumerateProtocols( int i ) const {
229 if ( i < 0 || static_cast<unsigned int>( i ) >= mAvailableProtocols.size() )
230 return 0;
231 return mAvailableProtocols[i];
232}
233
234namespace {
235 class CaseInsensitiveString {
236 const char * m;
237 public:
238 CaseInsensitiveString( const char * s ) : m( s ) {}
239#define make_operator( op ) \
240 bool operator op( const CaseInsensitiveString & other ) const { \
241 return tqstricmp( m, other.m ) op 0; \
242 } \
243 bool operator op( const char * other ) const { \
244 return tqstricmp( m, other ) op 0; \
245 }
246 make_operator( == )
247 make_operator( != )
248 make_operator( < )
249 make_operator( > )
250 make_operator( <= )
251 make_operator( >= )
252#undef make_operator
253 operator const char *() const { return m; }
254 };
255#define make_ext_operator( op, inv_op ) \
256 inline bool operator op( const char * lhs, const CaseInsensitiveString & rhs ) { \
257 return rhs.operator inv_op( lhs ); \
258 }
259 make_ext_operator( ==, == )
260 make_ext_operator( !=, != )
261 make_ext_operator( <, > )
262 make_ext_operator( >, < )
263 make_ext_operator( <=, >= )
264 make_ext_operator( >=, <= )
265#undef make_ext_operator
266
267}
268
269bool Kleo::CryptoBackendFactory::knowsAboutProtocol( const char * name ) const {
270 return std::find( mAvailableProtocols.begin(), mAvailableProtocols.end(),
271 CaseInsensitiveString( name ) ) != mAvailableProtocols.end();
272}
273
274#include "cryptobackendfactory.moc"
275
Main interface to crypto configuration.
Definition: cryptoconfig.h:334