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 
60 Kleo::CryptoBackendFactory * Kleo::CryptoBackendFactory::mSelf = 0;
61 
62 static const char * availableProtocols[] = {
63  "Chiasmus",
64  "OpenPGP", "SMIME",
65 };
66 static const unsigned int numAvailableProtocols = sizeof availableProtocols / sizeof *availableProtocols;
67 
68 Kleo::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 
87 Kleo::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 
98 Kleo::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 
113 const 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 
122 const 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 
131 const 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 
140 Kleo::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 
145 bool Kleo::CryptoBackendFactory::hasBackends() const {
146  return !mBackendList.empty();
147 }
148 
149 void 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 
165 const Kleo::CryptoBackend * Kleo::CryptoBackendFactory::backend( unsigned int idx ) const {
166  return ( idx < mBackendList.size() ) ? mBackendList[idx] : 0 ;
167 }
168 
169 const 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 
177 Kleo::BackendConfigWidget * Kleo::CryptoBackendFactory::configWidget( TQWidget * parent, const char * name ) const {
178  return new Kleo::BackendConfigWidget( mSelf, parent, name );
179 }
180 
181 TDEConfig* 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 
188 void Kleo::CryptoBackendFactory::setSMIMEBackend( const CryptoBackend* backend ) {
189  setProtocolBackend( "SMIME", backend );
190 }
191 
192 void Kleo::CryptoBackendFactory::setOpenPGPBackend( const CryptoBackend* backend ) {
193  setProtocolBackend( "OpenPGP", backend );
194 }
195 
196 void 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 
204 static 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 
219 void 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 
228 const 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 
234 namespace {
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 
269 bool 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