9f52b6f590997019b453a14bcb19a5a15d381347
[platform/upstream/libzypp.git] / zypp / KeyRing.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/KeyRing.cc
10  *
11 */
12 #include <iostream>
13 #include <fstream>
14 #include <sys/file.h>
15 #include <cstdio>
16 #include <unistd.h>
17
18 #include <boost/format.hpp>
19
20 #include "zypp/TmpPath.h"
21 #include "zypp/ZYppFactory.h"
22 #include "zypp/ZYpp.h"
23
24 #include "zypp/base/LogTools.h"
25 #include "zypp/base/IOStream.h"
26 #include "zypp/base/String.h"
27 #include "zypp/base/Regex.h"
28 #include "zypp/base/Gettext.h"
29 #include "zypp/base/WatchFile.h"
30 #include "zypp/PathInfo.h"
31 #include "zypp/KeyRing.h"
32 #include "zypp/ExternalProgram.h"
33 #include "zypp/TmpPath.h"
34
35 using std::endl;
36
37 #undef  ZYPP_BASE_LOGGER_LOGGROUP
38 #define ZYPP_BASE_LOGGER_LOGGROUP "zypp::KeyRing"
39
40 /** \todo Fix duplicate define in PublicKey/KeyRing */
41 #define GPG_BINARY "/usr/bin/gpg2"
42
43 ///////////////////////////////////////////////////////////////////
44 namespace zypp
45 { /////////////////////////////////////////////////////////////////
46
47   IMPL_PTR_TYPE(KeyRing);
48
49   namespace
50   {
51     KeyRing::DefaultAccept _keyRingDefaultAccept( KeyRing::ACCEPT_NOTHING );
52   }
53
54   KeyRing::DefaultAccept KeyRing::defaultAccept()
55   { return _keyRingDefaultAccept; }
56
57   void KeyRing::setDefaultAccept( DefaultAccept value_r )
58   {
59     MIL << "Set new KeyRing::DefaultAccept: " << value_r << endl;
60     _keyRingDefaultAccept = value_r;
61   }
62
63   void KeyRingReport::infoVerify( const std::string & file_r, const PublicKeyData & keyData_r, const KeyContext & keycontext )
64   {}
65
66   bool KeyRingReport::askUserToAcceptUnsignedFile( const std::string & file, const KeyContext & keycontext )
67   { return _keyRingDefaultAccept.testFlag( KeyRing::ACCEPT_UNSIGNED_FILE ); }
68
69   KeyRingReport::KeyTrust
70   KeyRingReport::askUserToAcceptKey( const PublicKey & key, const KeyContext & keycontext )
71   {
72     if ( _keyRingDefaultAccept.testFlag( KeyRing::TRUST_KEY_TEMPORARILY ) )
73       return KEY_TRUST_TEMPORARILY;
74     if ( _keyRingDefaultAccept.testFlag( KeyRing::TRUST_AND_IMPORT_KEY ) )
75       return KEY_TRUST_AND_IMPORT;
76     return KEY_DONT_TRUST;
77   }
78
79   bool KeyRingReport::askUserToAcceptUnknownKey( const std::string & file, const std::string & id, const KeyContext & keycontext )
80   { return _keyRingDefaultAccept.testFlag( KeyRing::ACCEPT_UNKNOWNKEY ); }
81
82   bool KeyRingReport::askUserToAcceptVerificationFailed( const std::string & file, const PublicKey & key, const KeyContext & keycontext )
83   { return _keyRingDefaultAccept.testFlag( KeyRing::ACCEPT_VERIFICATION_FAILED ); }
84
85   namespace
86   {
87     ///////////////////////////////////////////////////////////////////
88     /// \class CachedPublicKeyData
89     /// \brief Functor returning the keyrings data (cached).
90     /// \code
91     ///   const std::list<PublicKeyData> & cachedPublicKeyData( const Pathname & keyring );
92     /// \endcode
93     ///////////////////////////////////////////////////////////////////
94     struct CachedPublicKeyData // : private base::NonCopyable - but KeyRing uses RWCOW though also NonCopyable :(
95     {
96       const std::list<PublicKeyData> & operator()( const Pathname & keyring_r ) const
97       { return getData( keyring_r ); }
98
99     private:
100       struct Cache
101       {
102         // Empty copy ctor to allow insert into std::map as
103         // scoped_ptr is noncopyable.
104         Cache() {}
105         Cache( const Cache & rhs ) {}
106
107         void assertCache( const Pathname & keyring_r )
108         {
109           // .kbx since gpg2-2.1
110           if ( !_keyringK )
111             _keyringK.reset( new WatchFile( keyring_r/"pubring.kbx", WatchFile::NO_INIT ) );
112           if ( !_keyringP )
113             _keyringP.reset( new WatchFile( keyring_r/"pubring.gpg", WatchFile::NO_INIT ) );
114         }
115
116         bool hasChanged() const
117         {
118           bool k = _keyringK->hasChanged();     // be sure both files are checked
119           bool p = _keyringP->hasChanged();
120           return k || p;
121         }
122
123         std::list<PublicKeyData> _data;
124
125       private:
126         scoped_ptr<WatchFile> _keyringK;
127         scoped_ptr<WatchFile> _keyringP;
128       };
129
130       typedef std::map<Pathname,Cache> CacheMap;
131
132       const std::list<PublicKeyData> & getData( const Pathname & keyring_r ) const
133       {
134         Cache & cache( _cacheMap[keyring_r] );
135         // init new cache entry
136         cache.assertCache( keyring_r );
137         return getData( keyring_r, cache );
138       }
139
140       const std::list<PublicKeyData> & getData( const Pathname & keyring_r, Cache & cache_r ) const
141       {
142         if ( cache_r.hasChanged() )
143         {
144           const char* argv[] =
145           {
146             GPG_BINARY,
147             "--list-public-keys",
148             "--homedir", keyring_r.c_str(),
149             "--no-default-keyring",
150             "--quiet",
151             "--with-colons",
152             "--fixed-list-mode",
153             "--with-fingerprint",
154             "--with-sig-list",
155             "--no-tty",
156             "--no-greeting",
157             "--batch",
158             "--status-fd", "1",
159             NULL
160           };
161
162           PublicKeyScanner scanner;
163           ExternalProgram prog( argv ,ExternalProgram::Discard_Stderr, false, -1, true );
164           for( std::string line = prog.receiveLine(); !line.empty(); line = prog.receiveLine() )
165           {
166             scanner.scan( line );
167           }
168           prog.close();
169
170           cache_r._data.swap( scanner._keys );
171           MIL << "Found keys: " << cache_r._data  << endl;
172         }
173         return cache_r._data;
174       }
175
176       mutable CacheMap _cacheMap;
177     };
178     ///////////////////////////////////////////////////////////////////
179   }
180
181   ///////////////////////////////////////////////////////////////////
182   //
183   //    CLASS NAME : KeyRing::Impl
184   //
185   /** KeyRing implementation. */
186   struct KeyRing::Impl
187   {
188     Impl( const Pathname & baseTmpDir )
189     : _trusted_tmp_dir( baseTmpDir, "zypp-trusted-kr" )
190     , _general_tmp_dir( baseTmpDir, "zypp-general-kr" )
191     , _base_dir( baseTmpDir )
192     {
193       MIL << "Current KeyRing::DefaultAccept: " << _keyRingDefaultAccept << endl;
194     }
195
196     void importKey( const PublicKey & key, bool trusted = false );
197     void multiKeyImport( const Pathname & keyfile_r, bool trusted_r = false );
198     void deleteKey( const std::string & id, bool trusted );
199
200     std::string readSignatureKeyId( const Pathname & signature );
201
202     bool isKeyTrusted( const std::string & id )
203     { return bool(publicKeyExists( id, trustedKeyRing() )); }
204     bool isKeyKnown( const std::string & id )
205     { return publicKeyExists( id, trustedKeyRing() ) || publicKeyExists( id, generalKeyRing() ); }
206
207     std::list<PublicKey> trustedPublicKeys()
208     { return publicKeys( trustedKeyRing() ); }
209     std::list<PublicKey> publicKeys()
210     { return publicKeys( generalKeyRing() ); }
211
212     const std::list<PublicKeyData> & trustedPublicKeyData()
213     { return publicKeyData( trustedKeyRing() ); }
214     const std::list<PublicKeyData> & publicKeyData()
215     { return publicKeyData( generalKeyRing() ); }
216
217     void dumpPublicKey( const std::string & id, bool trusted, std::ostream & stream )
218     { dumpPublicKey( id, ( trusted ? trustedKeyRing() : generalKeyRing() ), stream ); }
219
220     PublicKey exportPublicKey( const PublicKeyData & keyData )
221     { return exportKey( keyData, generalKeyRing() ); }
222     PublicKey exportTrustedPublicKey( const PublicKeyData & keyData )
223     { return exportKey( keyData, trustedKeyRing() ); }
224
225     bool verifyFileSignatureWorkflow( const Pathname & file, const std::string & filedesc, const Pathname & signature, bool & sigValid_r, const KeyContext & keycontext = KeyContext());
226
227     bool verifyFileSignature( const Pathname & file, const Pathname & signature )
228     { return verifyFile( file, signature, generalKeyRing() ); }
229     bool verifyFileTrustedSignature( const Pathname & file, const Pathname & signature )
230     { return verifyFile( file, signature, trustedKeyRing() ); }
231
232   private:
233     bool verifyFile( const Pathname & file, const Pathname & signature, const Pathname & keyring );
234     void importKey( const Pathname & keyfile, const Pathname & keyring );
235
236     PublicKey exportKey( const std::string & id, const Pathname & keyring );
237     PublicKey exportKey( const PublicKeyData & keyData, const Pathname & keyring );
238
239     void dumpPublicKey( const std::string & id, const Pathname & keyring, std::ostream & stream );
240     filesystem::TmpFile dumpPublicKeyToTmp( const std::string & id, const Pathname & keyring );
241
242     void deleteKey( const std::string & id, const Pathname & keyring );
243
244     std::list<PublicKey> publicKeys( const Pathname & keyring);
245     const std::list<PublicKeyData> & publicKeyData( const Pathname & keyring )
246     { return cachedPublicKeyData( keyring ); }
247
248     /** Get \ref PublicKeyData for ID (\c false if ID is not found). */
249     PublicKeyData publicKeyExists( const std::string & id, const Pathname & keyring );
250
251     const Pathname generalKeyRing() const
252     { return _general_tmp_dir.path(); }
253     const Pathname trustedKeyRing() const
254     { return _trusted_tmp_dir.path(); }
255
256     // Used for trusted and untrusted keyrings
257     filesystem::TmpDir _trusted_tmp_dir;
258     filesystem::TmpDir _general_tmp_dir;
259     Pathname _base_dir;
260
261   private:
262     /** Functor returning the keyrings data (cached).
263      * \code
264      *  const std::list<PublicKeyData> & cachedPublicKeyData( const Pathname & keyring );
265      * \endcode
266      */
267     CachedPublicKeyData cachedPublicKeyData;
268   };
269   ///////////////////////////////////////////////////////////////////
270
271
272   void KeyRing::Impl::importKey( const PublicKey & key, bool trusted )
273   {
274     importKey( key.path(), trusted ? trustedKeyRing() : generalKeyRing() );
275
276     if ( trusted )
277     {
278       callback::SendReport<target::rpm::KeyRingSignals> rpmdbEmitSignal;
279       callback::SendReport<KeyRingSignals> emitSignal;
280
281       rpmdbEmitSignal->trustedKeyAdded( key );
282       emitSignal->trustedKeyAdded( key );
283     }
284   }
285
286   void KeyRing::Impl::multiKeyImport( const Pathname & keyfile_r, bool trusted_r )
287   {
288     importKey( keyfile_r, trusted_r ? trustedKeyRing() : generalKeyRing() );
289   }
290
291   void KeyRing::Impl::deleteKey( const std::string & id, bool trusted )
292   {
293     PublicKey key;
294
295     if ( trusted )
296     {
297         key = exportKey( id, trustedKeyRing() );
298     }
299
300     deleteKey( id, trusted ? trustedKeyRing() : generalKeyRing() );
301
302     if ( trusted )
303     {
304       callback::SendReport<target::rpm::KeyRingSignals> rpmdbEmitSignal;
305       callback::SendReport<KeyRingSignals> emitSignal;
306
307       rpmdbEmitSignal->trustedKeyRemoved( key );
308       emitSignal->trustedKeyRemoved( key );
309     }
310   }
311
312   PublicKeyData KeyRing::Impl::publicKeyExists( const std::string & id, const Pathname & keyring )
313   {
314     MIL << "Searching key [" << id << "] in keyring " << keyring << endl;
315     const std::list<PublicKeyData> & keys( publicKeyData( keyring ) );
316     for_( it, keys.begin(), keys.end() )
317     {
318       if ( id == (*it).id() )
319       {
320         return *it;
321       }
322     }
323     return PublicKeyData();
324   }
325
326   PublicKey KeyRing::Impl::exportKey( const PublicKeyData & keyData, const Pathname & keyring )
327   {
328     return PublicKey( dumpPublicKeyToTmp( keyData.id(), keyring ), keyData );
329   }
330
331   PublicKey KeyRing::Impl::exportKey( const std::string & id, const Pathname & keyring )
332   {
333     PublicKeyData keyData( publicKeyExists( id, keyring ) );
334     if ( keyData )
335       return PublicKey( dumpPublicKeyToTmp( keyData.id(), keyring ), keyData );
336
337     // Here: key not found
338     WAR << "No key " << id << " to export from " << keyring << endl;
339     return PublicKey();
340   }
341
342
343   void KeyRing::Impl::dumpPublicKey( const std::string & id, const Pathname & keyring, std::ostream & stream )
344   {
345     const char* argv[] =
346     {
347       GPG_BINARY,
348       "-a",
349       "--export",
350       "--homedir", keyring.asString().c_str(),
351       "--no-default-keyring",
352       "--quiet",
353       "--no-tty",
354       "--no-greeting",
355       "--no-permission-warning",
356       "--batch",
357       id.c_str(),
358       NULL
359     };
360     ExternalProgram prog( argv,ExternalProgram::Discard_Stderr, false, -1, true );
361     for ( std::string line = prog.receiveLine(); !line.empty(); line = prog.receiveLine() )
362     {
363       stream << line;
364     }
365     prog.close();
366   }
367
368   filesystem::TmpFile KeyRing::Impl::dumpPublicKeyToTmp( const std::string & id, const Pathname & keyring )
369   {
370     filesystem::TmpFile tmpFile( _base_dir, "pubkey-"+id+"-" );
371     MIL << "Going to export key " << id << " from " << keyring << " to " << tmpFile.path() << endl;
372
373     std::ofstream os( tmpFile.path().c_str() );
374     dumpPublicKey( id, keyring, os );
375     os.close();
376     return tmpFile;
377   }
378
379   bool KeyRing::Impl::verifyFileSignatureWorkflow( const Pathname & file, const std::string & filedesc, const Pathname & signature, bool & sigValid_r, const KeyContext & context )
380   {
381     sigValid_r = false; // set true if signature is actually successfully validated!
382
383     callback::SendReport<KeyRingReport> report;
384     MIL << "Going to verify signature for " << filedesc << " ( " << file << " ) with " << signature << endl;
385
386     // if signature does not exists, ask user if he wants to accept unsigned file.
387     if( signature.empty() || (!PathInfo( signature ).isExist()) )
388     {
389       bool res = report->askUserToAcceptUnsignedFile( filedesc, context );
390       MIL << "User decision on unsigned file: " << res << endl;
391       return res;
392     }
393
394     // get the id of the signature
395     std::string id = readSignatureKeyId( signature );
396
397     // doeskey exists in trusted keyring
398     PublicKeyData trustedKeyData( publicKeyExists( id, trustedKeyRing() ) );
399     if ( trustedKeyData )
400     {
401       MIL << "Key is trusted: " << trustedKeyData << endl;
402
403       // lets look if there is an updated key in the
404       // general keyring
405       PublicKeyData generalKeyData( publicKeyExists( id, generalKeyRing() ) );
406       if ( generalKeyData )
407       {
408         // bnc #393160: Comment #30: Compare at least the fingerprint
409         // in case an attacker created a key the the same id.
410         if ( trustedKeyData.fingerprint() == generalKeyData.fingerprint()
411            && trustedKeyData.created() < generalKeyData.created() )
412         {
413           MIL << "Key was updated. Saving new version into trusted keyring: " << generalKeyData << endl;
414           importKey( exportKey( generalKeyData, generalKeyRing() ), true );
415           trustedKeyData = generalKeyData = PublicKeyData(); // invalidated by import.
416         }
417       }
418
419       if ( ! trustedKeyData )   // invalidated by previous import
420         trustedKeyData = publicKeyExists( id, trustedKeyRing() );
421       report->infoVerify( filedesc, trustedKeyData, context );
422
423       // it exists, is trusted, does it validates?
424       if ( verifyFile( file, signature, trustedKeyRing() ) )
425       {
426         return (sigValid_r=true);       // signature is actually successfully validated!
427       }
428       else
429       {
430         return report->askUserToAcceptVerificationFailed( filedesc, exportKey( trustedKeyData, trustedKeyRing() ), context );
431       }
432     }
433     else
434     {
435       PublicKeyData generalKeyData( publicKeyExists( id, generalKeyRing() ) );
436       if ( generalKeyData )
437       {
438         PublicKey key( exportKey( generalKeyData, generalKeyRing() ) );
439         MIL << "Exported key " << id << " to " << key.path() << endl;
440         MIL << "Key " << id << " " << key.name() << " is not trusted" << endl;
441
442         // ok the key is not trusted, ask the user to trust it or not
443         KeyRingReport::KeyTrust reply = report->askUserToAcceptKey( key, context );
444         if ( reply == KeyRingReport::KEY_TRUST_TEMPORARILY ||
445             reply == KeyRingReport::KEY_TRUST_AND_IMPORT )
446         {
447           MIL << "User wants to trust key " << id << " " << key.name() << endl;
448           //dumpFile( unKey.path() );
449
450           Pathname whichKeyring;
451           if ( reply == KeyRingReport::KEY_TRUST_AND_IMPORT )
452           {
453             MIL << "User wants to import key " << id << " " << key.name() << endl;
454             importKey( key, true );
455             whichKeyring = trustedKeyRing();
456           }
457           else
458             whichKeyring = generalKeyRing();
459
460           // emit key added
461           if ( verifyFile( file, signature, whichKeyring ) )
462           {
463             MIL << "File signature is verified" << endl;
464             return (sigValid_r=true);   // signature is actually successfully validated!
465           }
466           else
467           {
468             MIL << "File signature check fails" << endl;
469             if ( report->askUserToAcceptVerificationFailed( filedesc, key, context ) )
470             {
471               MIL << "User continues anyway." << endl;
472               return true;
473             }
474             else
475             {
476               MIL << "User does not want to continue" << endl;
477               return false;
478             }
479           }
480         }
481         else
482         {
483           MIL << "User does not want to trust key " << id << " " << key.name() << endl;
484           return false;
485         }
486       }
487       else
488       {
489         // unknown key...
490         MIL << "File [" << file << "] ( " << filedesc << " ) signed with unknown key [" << id << "]" << endl;
491         if ( report->askUserToAcceptUnknownKey( filedesc, id, context ) )
492         {
493           MIL << "User wants to accept unknown key " << id << endl;
494           return true;
495         }
496         else
497         {
498           MIL << "User does not want to accept unknown key " << id << endl;
499           return false;
500         }
501       }
502     }
503     return false;
504   }
505
506   std::list<PublicKey> KeyRing::Impl::publicKeys( const Pathname & keyring )
507   {
508     const std::list<PublicKeyData> & keys( publicKeyData( keyring ) );
509     std::list<PublicKey> ret;
510
511     for_( it, keys.begin(), keys.end() )
512     {
513       PublicKey key( exportKey( *it, keyring ) );
514       ret.push_back( key );
515       MIL << "Found key " << key << endl;
516     }
517     return ret;
518   }
519
520   void KeyRing::Impl::importKey( const Pathname & keyfile, const Pathname & keyring )
521   {
522     if ( ! PathInfo( keyfile ).isExist() )
523       // TranslatorExplanation first %s is key name, second is keyring name
524       ZYPP_THROW(KeyRingException(boost::str(boost::format(
525           _("Tried to import not existent key %s into keyring %s"))
526           % keyfile.asString() % keyring.asString())));
527
528     const char* argv[] =
529     {
530       GPG_BINARY,
531       "--import",
532       "--homedir", keyring.asString().c_str(),
533       "--no-default-keyring",
534       "--quiet",
535       "--no-tty",
536       "--no-greeting",
537       "--no-permission-warning",
538       "--status-fd", "1",
539       keyfile.asString().c_str(),
540       NULL
541     };
542
543     ExternalProgram prog( argv,ExternalProgram::Discard_Stderr, false, -1, true );
544     prog.close();
545   }
546
547   void KeyRing::Impl::deleteKey( const std::string & id, const Pathname & keyring )
548   {
549     const char* argv[] =
550     {
551       GPG_BINARY,
552       "--delete-keys",
553       "--homedir", keyring.asString().c_str(),
554       "--no-default-keyring",
555       "--yes",
556       "--quiet",
557       "--no-tty",
558       "--batch",
559       "--status-fd", "1",
560       id.c_str(),
561       NULL
562     };
563
564     ExternalProgram prog( argv,ExternalProgram::Discard_Stderr, false, -1, true );
565
566     int code = prog.close();
567     if ( code )
568       ZYPP_THROW(Exception(_("Failed to delete key.")));
569     else
570       MIL << "Deleted key " << id << " from keyring " << keyring << endl;
571   }
572
573
574   std::string KeyRing::Impl::readSignatureKeyId( const Pathname & signature )
575   {
576     if ( ! PathInfo( signature ).isFile() )
577       ZYPP_THROW(Exception(boost::str(boost::format(
578           _("Signature file %s not found"))% signature.asString())));
579
580     MIL << "Determining key id if signature " << signature << endl;
581     // HACK create a tmp keyring with no keys
582     filesystem::TmpDir dir( _base_dir, "fake-keyring" );
583
584     const char* argv[] =
585     {
586       GPG_BINARY,
587       "--homedir", dir.path().asString().c_str(),
588       "--no-default-keyring",
589       "--quiet",
590       "--no-tty",
591       "--no-greeting",
592       "--batch",
593       "--status-fd", "1",
594       signature.asString().c_str(),
595       NULL
596     };
597
598     ExternalProgram prog( argv,ExternalProgram::Discard_Stderr, false, -1, true );
599
600     std::string line;
601     int count = 0;
602
603     str::regex rxNoKey( "^\\[GNUPG:\\] NO_PUBKEY (.+)\n$" );
604     std::string id;
605     for( line = prog.receiveLine(), count=0; !line.empty(); line = prog.receiveLine(), count++ )
606     {
607       //MIL << "[" << line << "]" << endl;
608       str::smatch what;
609       if( str::regex_match( line, what, rxNoKey ) )
610       {
611         if ( what.size() >= 1 )
612         {
613           id = what[1];
614           break;
615         }
616         //dumpRegexpResults( what );
617       }
618     }
619
620     if ( count == 0 )
621     {
622       MIL << "no output" << endl;
623     }
624
625     MIL << "Determined key id [" << id << "] for signature " << signature << endl;
626     prog.close();
627     return id;
628   }
629
630   bool KeyRing::Impl::verifyFile( const Pathname & file, const Pathname & signature, const Pathname & keyring )
631   {
632     const char* argv[] =
633     {
634       GPG_BINARY,
635       "--verify",
636       "--homedir", keyring.asString().c_str(),
637       "--no-default-keyring",
638       "--quiet",
639       "--no-tty",
640       "--batch",
641       "--no-greeting",
642       "--status-fd", "1",
643       signature.asString().c_str(),
644       file.asString().c_str(),
645       NULL
646     };
647
648     // no need to parse output for now
649     //     [GNUPG:] SIG_ID yCc4u223XRJnLnVAIllvYbUd8mQ 2006-03-29 1143618744
650     //     [GNUPG:] GOODSIG A84EDAE89C800ACA SuSE Package Signing Key <build@suse.de>
651     //     gpg: Good signature from "SuSE Package Signing Key <build@suse.de>"
652     //     [GNUPG:] VALIDSIG 79C179B2E1C820C1890F9994A84EDAE89C800ACA 2006-03-29 1143618744 0 3 0 17 2 00 79C179B2E1C820C1890F9994A84EDAE89C800ACA
653     //     [GNUPG:] TRUST_UNDEFINED
654
655     //     [GNUPG:] ERRSIG A84EDAE89C800ACA 17 2 00 1143618744 9
656     //     [GNUPG:] NO_PUBKEY A84EDAE89C800ACA
657
658     ExternalProgram prog( argv,ExternalProgram::Discard_Stderr, false, -1, true );
659
660     return ( prog.close() == 0 ) ? true : false;
661   }
662
663   ///////////////////////////////////////////////////////////////////
664
665   ///////////////////////////////////////////////////////////////////
666   //
667   //    CLASS NAME : KeyRing
668   //
669   ///////////////////////////////////////////////////////////////////
670
671   KeyRing::KeyRing( const Pathname & baseTmpDir )
672   : _pimpl( new Impl( baseTmpDir ) )
673   {}
674
675   KeyRing::~KeyRing()
676   {}
677
678
679   void KeyRing::importKey( const PublicKey & key, bool trusted )
680   { _pimpl->importKey( key, trusted ); }
681
682   void KeyRing::multiKeyImport( const Pathname & keyfile_r, bool trusted_r )
683   { _pimpl->multiKeyImport( keyfile_r, trusted_r ); }
684
685   std::string KeyRing::readSignatureKeyId( const Pathname & signature )
686   { return _pimpl->readSignatureKeyId( signature ); }
687
688   void KeyRing::deleteKey( const std::string & id, bool trusted )
689   { _pimpl->deleteKey( id, trusted ); }
690
691   std::list<PublicKey> KeyRing::publicKeys()
692   { return _pimpl->publicKeys(); }
693
694   std:: list<PublicKey> KeyRing::trustedPublicKeys()
695   { return _pimpl->trustedPublicKeys(); }
696
697   std::list<PublicKeyData> KeyRing::publicKeyData()
698   { return _pimpl->publicKeyData(); }
699
700   std::list<PublicKeyData> KeyRing::trustedPublicKeyData()
701   { return _pimpl->trustedPublicKeyData(); }
702
703   bool KeyRing::verifyFileSignatureWorkflow( const Pathname & file, const std::string & filedesc, const Pathname & signature, bool & sigValid_r, const KeyContext & keycontext )
704   { return _pimpl->verifyFileSignatureWorkflow( file, filedesc, signature, sigValid_r, keycontext ); }
705
706   bool KeyRing::verifyFileSignatureWorkflow( const Pathname & file, const std::string filedesc, const Pathname & signature, const KeyContext & keycontext )
707   { bool unused; return _pimpl->verifyFileSignatureWorkflow( file, filedesc, signature, unused, keycontext ); }
708
709   bool KeyRing::verifyFileSignature( const Pathname & file, const Pathname & signature )
710   { return _pimpl->verifyFileSignature( file, signature ); }
711
712   bool KeyRing::verifyFileTrustedSignature( const Pathname & file, const Pathname & signature )
713   { return _pimpl->verifyFileTrustedSignature( file, signature ); }
714
715   void KeyRing::dumpPublicKey( const std::string & id, bool trusted, std::ostream & stream )
716   { _pimpl->dumpPublicKey( id, trusted, stream ); }
717
718   PublicKey KeyRing::exportPublicKey( const PublicKeyData & keyData )
719   { return _pimpl->exportPublicKey( keyData ); }
720
721   PublicKey KeyRing::exportTrustedPublicKey( const PublicKeyData & keyData )
722   { return _pimpl->exportTrustedPublicKey( keyData ); }
723
724   bool KeyRing::isKeyTrusted( const std::string & id )
725   { return _pimpl->isKeyTrusted( id ); }
726
727   bool KeyRing::isKeyKnown( const std::string & id )
728   { return _pimpl->isKeyKnown( id ); }
729
730   /////////////////////////////////////////////////////////////////
731 } // namespace zypp
732 ///////////////////////////////////////////////////////////////////