chiasmusbackend.cpp
1/*
2 chiasmusbackend.cpp
3
4 This file is part of libkleopatra, the KDE keymanagement library
5 Copyright (c) 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 "chiasmusbackend.h"
38
39#include "config_data.h"
40#include "obtainkeysjob.h"
41#include "chiasmusjob.h"
42
43#include "kleo/cryptoconfig.h"
44
45#include <tdelocale.h>
46#include <tdeconfig.h>
47#include <kshell.h>
48#include <kdebug.h>
49
50#include <tqstringlist.h>
51#include <tqvariant.h>
52#include <tqfileinfo.h>
53
54#include <map>
55#include <memory>
56
57#include <cassert>
58
59namespace {
60
61 //
62 // The usual TQVariant template helpers:
63 //
64
65 // to<> is a demarshaller. It's a class b/c you can't partially
66 // specialise function templates yet. However, to<> can be used as if
67 // it was a function: TQString s = to<TQString>( myVariant );
68 template <typename T> class to {};
69
70#define MAKE_TO( type, func ) \
71 template <> \
72 class to< type > { \
73 type m; \
74 public: \
75 to( const TQVariant & v ) : m( v.func() ) {} \
76 operator type() const { return m; } \
77 }
78
79 MAKE_TO( int, toInt );
80 MAKE_TO( unsigned int, toUInt );
81
82 template <>
83 class to<KURL> {
84 KURL m;
85 public:
86 to( const TQVariant & v ) {
87 m.setPath( v.toString() );
88 }
89 operator KURL() const { return m; }
90 };
91
92 template <typename T>
93 class to< TQValueList<T> > {
94 TQValueList<T> m;
95 public:
96 to( const TQVariant & v ) {
97 const TQValueList<TQVariant> vl = v.toList();
98 for ( TQValueList<TQVariant>::const_iterator it = vl.begin(), end = vl.end() ; it != end ; ++it )
99 m.push_back( to<T>( *it ) );
100 }
101 operator TQValueList<T> () const { return m; }
102 };
103
104 template <>
105 class to<KURL::List> {
106 KURL::List m;
107 public:
108 to( const TQVariant & v ) {
109 // wow, KURL::List is broken... it lacks conversion from and to TQVL<KURL>...
110 m += to< TQValueList<KURL> >( v );
111 }
112 operator KURL::List() const { return m; }
113 };
114
115
116 // from<> is the demarshaller. See to<> for why this is a class...
117
118 template <typename T>
119 struct from_helper : public TQVariant {
120 from_helper( const T & t ) : TQVariant( t ) {}
121 };
122
123 template <typename T>
124 TQVariant from( const T & t ) {
125 return from_helper<T>( t );
126 }
127
128 // some special types:
129 template <> struct from_helper<KURL> : public TQVariant {
130 from_helper( const KURL & url ) : TQVariant( url.path() ) {}
131 };
132 template <typename T> struct from_helper< TQValueList<T> > : public TQVariant {
133 from_helper( const TQValueList<T> & l ) {
134 TQValueList<TQVariant> result;
135 for ( typename TQValueList<T>::const_iterator it = l.begin(), end = l.end() ; it != end ; ++it )
136 result.push_back( from( *it ) );
137 TQVariant::operator=( result );
138 }
139 };
140 template <> struct from_helper<KURL::List> : public from_helper< TQValueList<KURL> > {
141 from_helper( const KURL::List & l ) : from_helper< TQValueList<KURL> >( l ) {}
142 };
143
144 class ChiasmusConfigEntry : public Kleo::CryptoConfigEntry {
145 unsigned int mIdx;
146 TQVariant mValue;
147 bool mDirty;
148 public:
149 ChiasmusConfigEntry( unsigned int i )
150 : Kleo::CryptoConfigEntry(),
151 mIdx( i ), mValue( defaultValue() ), mDirty( false )
152 {
153 assert( i < kleo_chiasmus_config_entries_dim );
154 }
155 TQString name() const { return kleo_chiasmus_config_entries[mIdx].name; }
156 TQString description() const { return i18n( kleo_chiasmus_config_entries[mIdx].description ); }
157 bool isOptional() const { return kleo_chiasmus_config_entries[mIdx].is_optional; }
158 bool isReadOnly() const { return false; }
159 bool isList() const { return kleo_chiasmus_config_entries[mIdx].is_list; }
160 bool isRuntime() const { return kleo_chiasmus_config_entries[mIdx].is_runtime; }
161 Level level() const { return static_cast<Level>( kleo_chiasmus_config_entries[mIdx].level ); }
162 ArgType argType() const { return static_cast<ArgType>( kleo_chiasmus_config_entries[mIdx].type ); }
163 bool isSet() const { return mValue != defaultValue(); }
164 bool boolValue() const { return mValue.toBool(); }
165 TQString stringValue() const { return mValue.toString(); }
166 int intValue() const { return mValue.toInt(); }
167 unsigned int uintValue() const { return mValue.toUInt(); }
168 KURL urlValue() const {
169 if ( argType() != ArgType_Path && argType() != ArgType_DirPath ) return KURL( mValue.toString() );
170 KURL u; u.setPath( mValue.toString() ); return u;
171 }
172 unsigned int numberOfTimesSet() const { return 0; }
173 TQStringList stringValueList() const { return mValue.toStringList(); }
174 TQValueList<int> intValueList() const { return to< TQValueList<int> >( mValue ); }
175 TQValueList<unsigned int> uintValueList() const { return to< TQValueList<unsigned int> >( mValue ); }
176 KURL::List urlValueList() const {
177 if ( argType() != ArgType_Path && argType()!= ArgType_DirPath ) return mValue.toStringList();
178 else return to<KURL::List>( mValue ); }
179 void resetToDefault() { mValue = defaultValue(); mDirty = false; }
180 void setBoolValue( bool value ) { setValue( TQVariant( value ) ); }
181 void setStringValue( const TQString & value ) { setValue( value ); }
182 void setIntValue( int value ) { setValue( value ); }
183 void setUIntValue( unsigned int value ) { setValue( value ); }
184 void setURLValue( const KURL & value ) {
185 if ( argType() != ArgType_Path && argType()!= ArgType_DirPath ) setValue( value.url() );
186 else setValue( value.path() );
187 }
188 void setNumberOfTimesSet( unsigned int ) {}
189 void setStringValueList( const TQStringList & value ) { setValue( value ); }
190 void setIntValueList( const TQValueList<int> & l ) { setValue( from( l ) ); }
191 void setUIntValueList( const TQValueList<unsigned int> & l ) { setValue( from( l ) ); }
192 void setURLValueList( const KURL::List & l ) { setValue( from( l ) ); }
193 bool isDirty() const { return mDirty; }
194
195 TQVariant value() const { return mValue; }
196
197 void sync( TDEConfigBase * config ) {
198 if ( !mDirty )
199 return;
200 mDirty = false;
201 config->writeEntry( kleo_chiasmus_config_entries[mIdx].name, mValue );
202 }
203 void read( const TDEConfigBase * config ) {
204 mDirty = false;
205 mValue = config->readPropertyEntry( kleo_chiasmus_config_entries[mIdx].name, defaultValue() );
206 }
207 private:
208 TQVariant defaultValue() const;
209 void setValue( const TQVariant & value ) { mValue = value; mDirty = true; }
210 };
211
212 TQVariant ChiasmusConfigEntry::defaultValue() const {
213 const kleo_chiasmus_config_data & data = kleo_chiasmus_config_entries[mIdx];
214 switch ( data.type ) {
215 default:
216 return TQVariant();
217 case ArgType_None:
218 if ( isList() )
219 return TQValueList<TQVariant>() << TQVariant( data.defaults.boolean.value );
220 else
221 return TQVariant( data.defaults.boolean.value );
222 case ArgType_String:
223 if ( isList() )
224 return TQStringList( TQString::fromLatin1( data.defaults.string ) );
225 else
226 return TQString::fromLatin1( data.defaults.string );
227 case ArgType_Int:
228 if ( isList() )
229 return TQValueList<TQVariant>() << data.defaults.integer;
230 else
231 return data.defaults.integer;
232 case ArgType_UInt:
233 if ( isList() )
234 return TQValueList<TQVariant>() << data.defaults.unsigned_integer;
235 else
236 return data.defaults.unsigned_integer;
237 case ArgType_Path:
238 case ArgType_DirPath:
239 if ( isList() )
240 return TQValueList<TQVariant>() << TQString::fromLatin1( data.defaults.path );
241 else
242 return TQString::fromLatin1( data.defaults.path );
243 case ArgType_URL:
244 case ArgType_LDAPURL:
245 if ( isList() )
246 return TQValueList<TQVariant>() << TQString::fromLatin1( data.defaults.url );
247 else
248 return TQString::fromLatin1( data.defaults.url );
249 }
250 }
251
252 class ChiasmusGeneralGroup : public Kleo::CryptoConfigGroup {
253 mutable std::map<TQString,ChiasmusConfigEntry*> mCache;
254 mutable TDEConfig * mConfigObject;
255 public:
256 ChiasmusGeneralGroup() : Kleo::CryptoConfigGroup(), mConfigObject( 0 ) {}
257 ~ChiasmusGeneralGroup() { clear(); delete mConfigObject; }
258 TQString name() const { return "General"; }
259 TQString iconName() const { return "chiasmus_chi"; }
260 TQString description() const { return i18n( "General" ); }
261 Kleo::CryptoConfigEntry::Level level() const { return Kleo::CryptoConfigEntry::Level_Basic; }
262 TQStringList entryList() const {
263 TQStringList result;
264 for ( unsigned int i = 0 ; i < kleo_chiasmus_config_entries_dim ; ++i )
265 result.push_back( kleo_chiasmus_config_entries[i].name );
266 return result;
267 }
268 Kleo::CryptoConfigEntry * entry( const TQString & name ) const {
269 if ( ChiasmusConfigEntry * entry = mCache[name] )
270 return entry;
271 const TDEConfigGroup group( configObject(), "Chiasmus" );
272 for ( unsigned int i = 0 ; i < kleo_chiasmus_config_entries_dim ; ++i )
273 if ( name == kleo_chiasmus_config_entries[i].name ) {
274 ChiasmusConfigEntry * entry = new ChiasmusConfigEntry( i );
275 entry->read( &group );
276 return mCache[name] = entry;
277 }
278 return 0;
279 }
280
281 void sync() {
282 TDEConfigGroup group( configObject(), "Chiasmus" );
283 for ( std::map<TQString,ChiasmusConfigEntry*>::const_iterator it = mCache.begin(), end = mCache.end() ; it != end ; ++it )
284 it->second->sync( &group );
285 group.sync();
286 clear();
287 }
288 private:
289 TDEConfig * configObject() const {
290 if ( !mConfigObject )
291 // this is unsafe. We're a lib, used by concurrent apps.
292 mConfigObject = new TDEConfig( "chiasmusbackendrc" );
293 return mConfigObject;
294 }
295 void clear() {
296 for ( std::map<TQString,ChiasmusConfigEntry*>::const_iterator it = mCache.begin(), end = mCache.end() ; it != end ; ++it )
297 delete it->second;
298 mCache.clear();
299 }
300 };
301
302 class ChiasmusComponent : public Kleo::CryptoConfigComponent {
303 mutable ChiasmusGeneralGroup * mGeneralGroup;
304 public:
305 ChiasmusComponent() : Kleo::CryptoConfigComponent(), mGeneralGroup( 0 ) {}
306 ~ChiasmusComponent() { delete mGeneralGroup; }
307
308 void sync() {
309 if ( mGeneralGroup )
310 mGeneralGroup->sync();
311 }
312
313 TQString name() const { return "Chiasmus"; }
314 TQString iconName() const { return "chiasmus_chi"; }
315 TQString description() const { return i18n( "Chiasmus" ); }
316 TQStringList groupList() const { return TQStringList() << "General"; }
317 Kleo::CryptoConfigGroup * group( const TQString & name ) const {
318 if ( name != "General" )
319 return 0;
320 if ( !mGeneralGroup )
321 mGeneralGroup = new ChiasmusGeneralGroup();
322 return mGeneralGroup;
323 }
324 };
325
326}
327
328class Kleo::ChiasmusBackend::CryptoConfig : public Kleo::CryptoConfig {
329 mutable ChiasmusComponent * mComponent;
330public:
331 CryptoConfig() : Kleo::CryptoConfig(), mComponent( 0 ) {}
332 ~CryptoConfig() { delete mComponent; }
333
334 TQStringList componentList() const { return TQStringList() << "Chiasmus" ; }
335 ChiasmusComponent * component( const TQString & name ) const {
336 if ( name != "Chiasmus" )
337 return 0;
338 if ( !mComponent )
339 mComponent = new ChiasmusComponent();
340 return mComponent;
341 }
342 void sync( bool ) {
343 if ( mComponent )
344 mComponent->sync();
345 }
346 void clear() { delete mComponent; mComponent = 0; }
347};
348
349class Kleo::ChiasmusBackend::Protocol : public Kleo::CryptoBackend::Protocol {
350 Kleo::CryptoConfig * mCryptoConfig;
351public:
352 Protocol( Kleo::CryptoConfig * config )
353 : Kleo::CryptoBackend::Protocol(), mCryptoConfig( config )
354 {
355 assert( config );
356 }
357 ~Protocol() {}
358
359 TQString name() const { return "Chiasmus"; }
360 TQString displayName() const { return i18n( "Chiasmus command line tool" ); }
361 KeyListJob * keyListJob( bool, bool, bool ) const { return 0; }
362 EncryptJob * encryptJob( bool, bool ) const { return 0; }
363 DecryptJob * decryptJob() const { return 0; }
364 SignJob * signJob( bool, bool ) const { return 0; }
365 VerifyDetachedJob * verifyDetachedJob( bool ) const { return 0; }
366 VerifyOpaqueJob * verifyOpaqueJob( bool ) const { return 0; }
367 KeyGenerationJob * keyGenerationJob() const { return 0; }
368 ImportJob * importJob() const { return 0; }
369 ExportJob * publicKeyExportJob( bool ) const { return 0; }
370 ExportJob * secretKeyExportJob( bool, const TQString& ) const { return 0; }
371 DownloadJob * downloadJob( bool ) const { return 0; }
372 DeleteJob * deleteJob() const { return 0; }
373 SignEncryptJob * signEncryptJob( bool, bool ) const { return 0; }
374 DecryptVerifyJob * decryptVerifyJob( bool ) const { return 0; }
375 RefreshKeysJob * refreshKeysJob() const { return 0; }
376
377 SpecialJob * specialJob( const char * type, const TQStringVariantMap & args ) const {
378 if ( tqstricmp( type, "x-obtain-keys" ) == 0 && args.size() == 0 )
379 return new ObtainKeysJob();
380 if ( tqstricmp( type, "x-encrypt" ) == 0 && args.size() == 0 )
381 return new ChiasmusJob( ChiasmusJob::Encrypt );
382 if ( tqstricmp( type, "x-decrypt" ) == 0 && args.size() == 0 )
383 return new ChiasmusJob( ChiasmusJob::Decrypt );
384 kdDebug(5150) << "ChiasmusBackend::Protocol: tried to instantiate unknown job type \""
385 << type << "\"" << endl;
386
387 return 0;
388 }
389};
390
391Kleo::ChiasmusBackend * Kleo::ChiasmusBackend::self = 0;
392
393Kleo::ChiasmusBackend::ChiasmusBackend()
394 : Kleo::CryptoBackend(),
395 mCryptoConfig( 0 ),
396 mProtocol( 0 )
397{
398 self = this;
399}
400
401Kleo::ChiasmusBackend::~ChiasmusBackend() {
402 self = 0;
403 delete mCryptoConfig;
404 delete mProtocol;
405}
406
407TQString Kleo::ChiasmusBackend::name() const {
408 return "Chiasmus";
409}
410
411TQString Kleo::ChiasmusBackend::displayName() const {
412 return i18n( "Chiasmus" );
413}
414
415Kleo::CryptoConfig * Kleo::ChiasmusBackend::config() const {
416 if ( !mCryptoConfig )
417 mCryptoConfig = new CryptoConfig();
418 return mCryptoConfig;
419}
420
421Kleo::CryptoBackend::Protocol * Kleo::ChiasmusBackend::protocol( const char * name ) const {
422 if ( tqstricmp( name, "Chiasmus" ) != 0 )
423 return 0;
424 if ( !mProtocol )
425 if ( checkForChiasmus() )
426 mProtocol = new Protocol( config() );
427 return mProtocol;
428}
429
430bool Kleo::ChiasmusBackend::checkForOpenPGP( TQString * reason ) const {
431 if ( reason )
432 *reason = i18n( "Unsupported protocol \"%1\"" ).arg( "OpenPGP" );
433 return false;
434}
435
436bool Kleo::ChiasmusBackend::checkForSMIME( TQString * reason ) const {
437 if ( reason )
438 *reason = i18n( "Unsupported protocol \"%1\"" ).arg( "SMIME" );
439 return false;
440}
441
442bool Kleo::ChiasmusBackend::checkForChiasmus( TQString * reason ) const {
443
444 // kills the protocol instance when we return false:
445 std::unique_ptr<Protocol> tmp( mProtocol );
446 mProtocol = 0;
447
448 const CryptoConfigEntry * path = config()->entry( "Chiasmus", "General", "path" );
449 assert( path ); assert( path->argType() == CryptoConfigEntry::ArgType_Path );
450 const TQString chiasmus = path->urlValue().path();
451 const TQFileInfo fi( KShell::tildeExpand( chiasmus ) );
452 if ( !fi.isExecutable() ) {
453 if ( reason )
454 *reason = i18n( "File \"%1\" does not exist or is not executable." ).arg( chiasmus );
455 return false;
456 }
457
458 // FIXME: more checks?
459 mProtocol = tmp.release();
460 return true;
461}
462
463bool Kleo::ChiasmusBackend::checkForProtocol( const char * name, TQString * reason ) const {
464 if ( tqstricmp( name, "Chiasmus" ) == 0 )
465 return checkForChiasmus( reason );
466 if ( reason )
467 *reason = i18n( "Unsupported protocol \"%1\"" ).arg( name );
468 return 0;
469}
470
471bool Kleo::ChiasmusBackend::supportsProtocol( const char * name ) const {
472 return tqstricmp( name, "Chiasmus" ) == 0;
473}
474
475const char * Kleo::ChiasmusBackend::enumerateProtocols( int i ) const {
476 return i == 0 ? "Chiasmus" : 0 ;
477}
Crypto config for one component (e.g.
Definition: cryptoconfig.h:295
virtual TQString name() const =0
Return the internal name of this component.
virtual TQString iconName() const =0
Return the name of the icon for this component.
virtual CryptoConfigGroup * group(const TQString &name) const =0
virtual TQString description() const =0
Return user-visible description of this component.
virtual TQStringList groupList() const =0
Returns the list of groups that are known about.
Description of a single option.
Definition: cryptoconfig.h:49
virtual void setBoolValue(bool)=0
Define whether the option is set or not (only allowed for ArgType_None)
virtual bool isList() const =0
virtual ArgType argType() const =0
Argument type.
virtual TQStringList stringValueList() const =0
Return value as a list of strings (mostly meaningful for String, Path and URL argtypes,...
virtual void setNumberOfTimesSet(unsigned int)=0
Set the number of times the option is set (only valid for ArgType_None, if isList())
virtual void setUIntValueList(const TQValueList< unsigned int > &)=0
Set a new list of unsigned int values.
virtual bool isDirty() const =0
virtual void setStringValueList(const TQStringList &)=0
Set a new string-list value (only allowed for String, Path and URL argtypes, if isList())
virtual bool isOptional() const =0
virtual KURL::List urlValueList() const =0
Return value as a list of URLs (only meaningful for Path and URL argtypes, if isList())
virtual TQString name() const =0
Return the internal name of this entry.
virtual void setURLValue(const KURL &)=0
Set value as a URL (only meaningful for Path (if local) and URL argtypes)
virtual TQString stringValue() const =0
Return value as a string (available for all argtypes) The returned string can be empty (explicitely s...
virtual unsigned int uintValue() const =0
Return value as an unsigned int.
virtual void setUIntValue(unsigned int)=0
Set a new unsigned int value.
virtual Level level() const =0
User level.
virtual TQString description() const =0
virtual bool boolValue() const =0
Return value as a bool (only allowed for ArgType_None)
virtual int intValue() const =0
Return value as a signed int.
virtual KURL urlValue() const =0
Return value as a URL (only meaningful for Path and URL argtypes)
virtual TQValueList< unsigned int > uintValueList() const =0
Return value as a list of unsigned ints.
virtual unsigned int numberOfTimesSet() const =0
Return number of times the option is set (only valid for ArgType_None, if isList())
virtual bool isRuntime() const =0
virtual void setURLValueList(const KURL::List &)=0
Set value as a URL list (only meaningful for Path (if all URLs are local) and URL argtypes,...
virtual void setStringValue(const TQString &)=0
Set string value (allowed for all argtypes)
virtual void setIntValueList(const TQValueList< int > &)=0
Set a new list of signed int values.
virtual TQValueList< int > intValueList() const =0
Return value as a list of signed ints.
virtual void resetToDefault()=0
Reset an option to its default value.
virtual bool isSet() const =0
Return true if the option is set, i.e.
virtual void setIntValue(int)=0
Set a new signed int value.
virtual bool isReadOnly() const =0
Group containing a set of config options.
Definition: cryptoconfig.h:252
virtual CryptoConfigEntry::Level level() const =0
User level.
virtual CryptoConfigEntry * entry(const TQString &name) const =0
virtual TQString description() const =0
virtual TQStringList entryList() const =0
Returns the list of entries that are known by this group.
virtual TQString iconName() const =0
Return the name of the icon for this group.
virtual TQString name() const =0
Return the internal name of this group.
Main interface to crypto configuration.
Definition: cryptoconfig.h:334
virtual void sync(bool runtime)=0
Write back changes.
virtual void clear()=0
Tells the CryptoConfig to discard any cached information, including all components,...
virtual TQStringList componentList() const =0
Returns the list of known components (e.g.
virtual CryptoConfigComponent * component(const TQString &name) const =0