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