KeyRing.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 #include <iostream>
00013 #include <fstream>
00014 #include <sys/file.h>
00015 #include <cstdio>
00016 #include <unistd.h>
00017 
00018 #include <boost/format.hpp>
00019 
00020 #include "zypp/TmpPath.h"
00021 #include "zypp/ZYppFactory.h"
00022 #include "zypp/ZYpp.h"
00023 
00024 #include "zypp/base/Logger.h"
00025 #include "zypp/base/IOStream.h"
00026 #include "zypp/base/String.h"
00027 #include "zypp/base/Regex.h"
00028 #include "zypp/base/Gettext.h"
00029 #include "zypp/PathInfo.h"
00030 #include "zypp/KeyRing.h"
00031 #include "zypp/ExternalProgram.h"
00032 #include "zypp/TmpPath.h"
00033 
00034 using namespace std;
00035 using namespace zypp::filesystem;
00036 
00037 #undef  ZYPP_BASE_LOGGER_LOGGROUP
00038 #define ZYPP_BASE_LOGGER_LOGGROUP "zypp::KeyRing"
00039 
00040 #define GPG_BINARY "/usr/bin/gpg2"
00041 
00043 namespace zypp
00044 { 
00045 
00046   IMPL_PTR_TYPE(KeyRing);
00047 
00048   namespace
00049   {
00050     KeyRing::DefaultAccept _keyRingDefaultAccept( KeyRing::ACCEPT_NOTHING );
00051   }
00052 
00053   KeyRing::DefaultAccept KeyRing::defaultAccept()
00054   { return _keyRingDefaultAccept; }
00055 
00056   void KeyRing::setDefaultAccept( DefaultAccept value_r )
00057   {
00058     MIL << "Set new KeyRing::DefaultAccept: " << value_r << endl;
00059     _keyRingDefaultAccept = value_r;
00060   }
00061 
00062   bool KeyRingReport::askUserToAcceptUnsignedFile( const string &file, const KeyContext &keycontext )
00063   { return _keyRingDefaultAccept.testFlag( KeyRing::ACCEPT_UNSIGNED_FILE ); }
00064 
00065   KeyRingReport::KeyTrust
00066   KeyRingReport::askUserToAcceptKey( const PublicKey &key, const KeyContext &keycontext )
00067   {
00068     if ( _keyRingDefaultAccept.testFlag( KeyRing::TRUST_KEY_TEMPORARILY ) )
00069       return KEY_TRUST_TEMPORARILY;
00070     if ( _keyRingDefaultAccept.testFlag( KeyRing::TRUST_AND_IMPORT_KEY ) )
00071       return KEY_TRUST_AND_IMPORT;
00072     return KEY_DONT_TRUST;
00073   }
00074 
00075   bool KeyRingReport::askUserToAcceptUnknownKey( const string &file, const string &id, const KeyContext &keycontext )
00076   { return _keyRingDefaultAccept.testFlag( KeyRing::ACCEPT_UNKNOWNKEY ); }
00077 
00078   bool KeyRingReport::askUserToAcceptVerificationFailed( const string &file, const PublicKey &key, const KeyContext &keycontext )
00079   { return _keyRingDefaultAccept.testFlag( KeyRing::ACCEPT_VERIFICATION_FAILED ); }
00080 
00082   //
00083   //    CLASS NAME : KeyRing::Impl
00084   //
00086   struct KeyRing::Impl
00087   {
00088     Impl( const Pathname & baseTmpDir )
00089     : _trusted_tmp_dir( baseTmpDir, "zypp-trusted-kr" )
00090     , _general_tmp_dir( baseTmpDir, "zypp-general-kr" )
00091     , _base_dir( baseTmpDir )
00092     {
00093       MIL << "Current KeyRing::DefaultAccept: " << _keyRingDefaultAccept << endl;
00094     }
00095 
00096     void importKey( const PublicKey &key, bool trusted = false);
00097     void deleteKey( const string &id, bool trusted );
00098 
00099     string readSignatureKeyId( const Pathname &signature );
00100 
00101     bool isKeyTrusted( const string &id);
00102     bool isKeyKnown( const string &id );
00103 
00104     list<PublicKey> trustedPublicKeys();
00105     list<PublicKey> publicKeys();
00106 
00107     list<string> trustedPublicKeyIds();
00108     list<string> publicKeyIds();
00109 
00110     void dumpPublicKey( const string &id, bool trusted, ostream &stream );
00111 
00112     bool verifyFileSignatureWorkflow(
00113         const Pathname &file,
00114         const string filedesc,
00115         const Pathname &signature,
00116         const KeyContext &keycontext = KeyContext());
00117 
00118     bool verifyFileSignature( const Pathname &file, const Pathname &signature);
00119     bool verifyFileTrustedSignature( const Pathname &file, const Pathname &signature);
00120   private:
00121     //mutable map<Locale, string> translations;
00122     bool verifyFile( const Pathname &file, const Pathname &signature, const Pathname &keyring);
00123     void importKey( const Pathname &keyfile, const Pathname &keyring);
00124     PublicKey exportKey( string id, const Pathname &keyring);
00125     void dumpPublicKey( const string &id, const Pathname &keyring, ostream &stream );
00126     void deleteKey( const string &id, const Pathname &keyring );
00127 
00128     list<PublicKey> publicKeys(const Pathname &keyring);
00129     list<string> publicKeyIds(const Pathname &keyring);
00130 
00131     bool publicKeyExists( string id, const Pathname &keyring);
00132 
00133     const Pathname generalKeyRing() const;
00134     const Pathname trustedKeyRing() const;
00135 
00136     // Used for trusted and untrusted keyrings
00137     TmpDir _trusted_tmp_dir;
00138     TmpDir _general_tmp_dir;
00139     Pathname _base_dir;
00140   public:
00142     static shared_ptr<Impl> nullimpl()
00143     {
00144       static shared_ptr<Impl> _nullimpl( new Impl( TmpPath::defaultLocation() ) );
00145       return _nullimpl;
00146     }
00147 
00148   private:
00149     friend Impl * rwcowClone<Impl>( const Impl * rhs );
00151     Impl * clone() const
00152     { return new Impl( *this ); }
00153   };
00154 
00155 
00156   const Pathname KeyRing::Impl::generalKeyRing() const
00157   {
00158     return _general_tmp_dir.path();
00159   }
00160 
00161   const Pathname KeyRing::Impl::trustedKeyRing() const
00162   {
00163     return _trusted_tmp_dir.path();
00164   }
00165 
00166   void KeyRing::Impl::importKey( const PublicKey &key, bool trusted)
00167   {
00168     callback::SendReport<target::rpm::KeyRingSignals> rpmdbEmitSignal;
00169     callback::SendReport<KeyRingSignals> emitSignal;
00170 
00171     importKey( key.path(), trusted ? trustedKeyRing() : generalKeyRing() );
00172 
00173     if ( trusted )
00174     {
00175       rpmdbEmitSignal->trustedKeyAdded( key );
00176       emitSignal->trustedKeyAdded( key );
00177     }
00178   }
00179 
00180   void KeyRing::Impl::deleteKey( const string &id, bool trusted)
00181   {
00182     PublicKey key;
00183 
00184     if (trusted)
00185     {
00186         key = exportKey(id, trustedKeyRing());
00187     }
00188 
00189     deleteKey( id, trusted ? trustedKeyRing() : generalKeyRing() );
00190 
00191     if ( trusted )
00192     {
00193       callback::SendReport<target::rpm::KeyRingSignals> rpmdbEmitSignal;
00194       callback::SendReport<KeyRingSignals> emitSignal;
00195 
00196       rpmdbEmitSignal->trustedKeyRemoved( key );
00197       emitSignal->trustedKeyRemoved( key );
00198     }
00199   }
00200 
00201   list<PublicKey> KeyRing::Impl::publicKeys()
00202   {
00203     return publicKeys( generalKeyRing() );
00204   }
00205 
00206   list<PublicKey> KeyRing::Impl::trustedPublicKeys()
00207   {
00208     return publicKeys( trustedKeyRing() );
00209   }
00210 
00211   list<string> KeyRing::Impl::publicKeyIds()
00212   {
00213     return publicKeyIds( generalKeyRing() );
00214   }
00215 
00216   list<string> KeyRing::Impl::trustedPublicKeyIds()
00217   {
00218     return publicKeyIds( trustedKeyRing() );
00219   }
00220 
00221   bool KeyRing::Impl::verifyFileTrustedSignature( const Pathname &file, const Pathname &signature)
00222   {
00223     return verifyFile( file, signature, trustedKeyRing() );
00224   }
00225 
00226   bool KeyRing::Impl::verifyFileSignature( const Pathname &file, const Pathname &signature)
00227   {
00228     return verifyFile( file, signature, generalKeyRing() );
00229   }
00230 
00231   bool KeyRing::Impl::isKeyTrusted( const string &id)
00232   {
00233     return publicKeyExists( id, trustedKeyRing() );
00234   }
00235 
00236   bool KeyRing::Impl::isKeyKnown( const string &id )
00237   {
00238     MIL << endl;
00239     if ( publicKeyExists( id, trustedKeyRing() ) )
00240       return true;
00241     else
00242       return publicKeyExists( id, generalKeyRing() );
00243   }
00244 
00245   bool KeyRing::Impl::publicKeyExists( string id, const Pathname &keyring)
00246   {
00247     MIL << "Searching key [" << id << "] in keyring " << keyring << endl;
00248     list<PublicKey> keys = publicKeys(keyring);
00249     for (list<PublicKey>::const_iterator it = keys.begin(); it != keys.end(); it++)
00250     {
00251       if ( id == (*it).id() )
00252 
00253         return true;
00254     }
00255     return false;
00256   }
00257 
00258   PublicKey KeyRing::Impl::exportKey( string id, const Pathname &keyring)
00259   {
00260     TmpFile tmp_file( _base_dir, "pubkey-"+id+"-" );
00261     MIL << "Going to export key " << id << " from " << keyring << " to " << tmp_file.path() << endl;
00262 
00263     try {
00264       ofstream os(tmp_file.path().c_str());
00265       dumpPublicKey( id, keyring, os );
00266       os.close();
00267       return PublicKey( tmp_file );
00268     }
00269     catch (BadKeyException &e)
00270     {
00271       ERR << "Cannot create public key " << id << " from " << keyring << " keyring  to file " << e.keyFile() << endl;
00272       // TranslatorExplanation first %s is key name, second is keyring name
00273       // and third is keyfile name
00274       ZYPP_THROW(Exception(boost::str(boost::format(
00275           _("Cannot create public key %s from %s keyring to file %s"))
00276           % id % keyring.asString() % e.keyFile().asString())));
00277     }
00278     catch (exception &e)
00279     {
00280       ERR << "Cannot export key " << id << " from " << keyring << " keyring  to file " << tmp_file.path() << endl;
00281     }
00282     return PublicKey();
00283   }
00284 
00285   void KeyRing::Impl::dumpPublicKey( const string &id, bool trusted, ostream &stream )
00286   {
00287      dumpPublicKey( id, ( trusted ? trustedKeyRing() : generalKeyRing() ), stream );
00288   }
00289 
00290   void KeyRing::Impl::dumpPublicKey( const string &id, const Pathname &keyring, ostream &stream )
00291   {
00292     const char* argv[] =
00293     {
00294       GPG_BINARY,
00295       "--no-default-keyring",
00296       "--quiet",
00297       "--no-tty",
00298       "--no-greeting",
00299       "--no-permission-warning",
00300       "--batch",
00301       "--homedir",
00302       keyring.asString().c_str(),
00303       "-a",
00304       "--export",
00305       id.c_str(),
00306       NULL
00307     };
00308     ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
00309     string line;
00310     int count;
00311     for(line = prog.receiveLine(), count=0; !line.empty(); line = prog.receiveLine(), count++ )
00312     {
00313       stream << line;
00314     }
00315     prog.close();
00316   }
00317 
00318 
00319   bool KeyRing::Impl::verifyFileSignatureWorkflow(
00320       const Pathname &file,
00321       const string filedesc,
00322       const Pathname &signature,
00323       const KeyContext &context)
00324   {
00325     callback::SendReport<KeyRingReport> report;
00326     //callback::SendReport<KeyRingSignals> emitSignal;
00327     MIL << "Going to verify signature for " << filedesc << " ( " << file << " ) with " << signature << endl;
00328 
00329     // if signature does not exists, ask user if he wants to accept unsigned file.
00330     if( signature.empty() || (!PathInfo(signature).isExist()) )
00331     {
00332       bool res = report->askUserToAcceptUnsignedFile( filedesc, context );
00333       MIL << "User decision on unsigned file: " << res << endl;
00334       return res;
00335     }
00336 
00337     // get the id of the signature
00338     string id = readSignatureKeyId(signature);
00339 
00340     // doeskey exists in trusted keyring
00341     if ( publicKeyExists( id, trustedKeyRing() ) )
00342     {
00343       PublicKey key = exportKey( id, trustedKeyRing() );
00344 
00345       // lets look if there is an updated key in the
00346       // general keyring
00347       if ( publicKeyExists( id, generalKeyRing() ) )
00348       {
00349         // bnc #393160: Comment #30: Compare at least the fingerprint
00350         // in case an attacker created a key the the same id.
00351         PublicKey untkey = exportKey( id, generalKeyRing() );
00352         if ( untkey.fingerprint() == key.fingerprint()
00353              && untkey.created() > key.created() )
00354         {
00355           MIL << "Key " << key << " was updated. Saving new version into trusted keyring." << endl;
00356           importKey( untkey, true );
00357           key = untkey;
00358         }
00359       }
00360 
00361       MIL << "Key " << id << " " << key.name() << " is trusted" << endl;
00362       // it exists, is trusted, does it validates?
00363       if ( verifyFile( file, signature, trustedKeyRing() ) )
00364         return true;
00365       else
00366         return report->askUserToAcceptVerificationFailed( filedesc, key, context );
00367     }
00368     else
00369     {
00370       if ( publicKeyExists( id, generalKeyRing() ) )
00371       {
00372         PublicKey key =  exportKey( id, generalKeyRing());
00373         MIL << "Exported key " << id << " to " << key.path() << endl;
00374         MIL << "Key " << id << " " << key.name() << " is not trusted" << endl;
00375 
00376         // ok the key is not trusted, ask the user to trust it or not
00377         KeyRingReport::KeyTrust reply = report->askUserToAcceptKey(key, context);
00378         if (reply == KeyRingReport::KEY_TRUST_TEMPORARILY ||
00379             reply == KeyRingReport::KEY_TRUST_AND_IMPORT)
00380         {
00381           MIL << "User wants to trust key " << id << " " << key.name() << endl;
00382           //dumpFile(unKey.path());
00383 
00384           Pathname which_keyring;
00385           if (reply == KeyRingReport::KEY_TRUST_AND_IMPORT)
00386           {
00387             MIL << "User wants to import key " << id << " " << key.name() << endl;
00388             importKey( key, true );
00389             which_keyring = trustedKeyRing();
00390           }
00391           else
00392             which_keyring = generalKeyRing();
00393 
00394           // emit key added
00395           if ( verifyFile( file, signature, which_keyring ) )
00396           {
00397             MIL << "File signature is verified" << endl;
00398             return true;
00399           }
00400           else
00401           {
00402             MIL << "File signature check fails" << endl;
00403             if ( report->askUserToAcceptVerificationFailed( filedesc, key, context ) )
00404             {
00405               MIL << "User continues anyway." << endl;
00406               return true;
00407             }
00408             else
00409             {
00410               MIL << "User does not want to continue" << endl;
00411               return false;
00412             }
00413           }
00414         }
00415         else
00416         {
00417           MIL << "User does not want to trust key " << id << " " << key.name() << endl;
00418           return false;
00419         }
00420       }
00421       else
00422       {
00423         // unknown key...
00424         MIL << "File [" << file << "] ( " << filedesc << " ) signed with unknown key [" << id << "]" << endl;
00425         if ( report->askUserToAcceptUnknownKey( filedesc, id, context ) )
00426         {
00427           MIL << "User wants to accept unknown key " << id << endl;
00428           return true;
00429         }
00430         else
00431         {
00432           MIL << "User does not want to accept unknown key " << id << endl;
00433           return false;
00434         }
00435       }
00436     }
00437     return false;
00438   }
00439 
00440   list<string> KeyRing::Impl::publicKeyIds(const Pathname &keyring)
00441   {
00442     static str::regex rxColons("^([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):\n$");
00443     static str::regex rxColonsFpr("^([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):\n$");
00444 
00445     list<string> ids;
00446 
00447     const char* argv[] =
00448     {
00449       GPG_BINARY,
00450       "--no-default-keyring",
00451       "--quiet",
00452       "--list-public-keys",
00453       "--fixed-list-mode",
00454       "--with-colons",
00455       "--with-fingerprint",
00456       "--no-tty",
00457       "--no-greeting",
00458       "--batch",
00459       "--status-fd",
00460       "1",
00461       "--homedir",
00462       keyring.asString().c_str(),
00463       NULL
00464     };
00465 
00466     ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
00467     string line;
00468     int count = 0;
00469 
00470     for(line = prog.receiveLine(), count=0; !line.empty(); line = prog.receiveLine(), count++ )
00471     {
00472       //MIL << line << endl;
00473       str::smatch what;
00474       if(str::regex_match(line, what, rxColons))
00475       {
00476         string id;
00477         string fingerprint;
00478         if ( what[1] == "pub" )
00479         {
00480           id = what[5];
00481 
00482           string line2;
00483           for(line2 = prog.receiveLine(); !line2.empty(); line2 = prog.receiveLine(), count++ )
00484           {
00485             str::smatch what2;
00486             if (str::regex_match(line2, what2, rxColonsFpr))
00487             {
00488               if ( (what2[1] == "fpr") && (what2[1] != "pub") && (what2[1] !="sub"))
00489               {
00490                 fingerprint = what2[10];
00491                 break;
00492               }
00493             }
00494           }
00495 
00496           ids.push_back(id);
00497           MIL << "Found key " << "[" << id << "]" << endl;
00498         }
00499         //dumpRegexpResults(what);
00500       }
00501     }
00502     prog.close();
00503     return ids;
00504   }
00505 
00506   list<PublicKey> KeyRing::Impl::publicKeys(const Pathname &keyring)
00507   {
00508 
00509     list<PublicKey> keys;
00510 
00511     list<string> ids = publicKeyIds(keyring);
00512 
00513     for ( list<string>::const_iterator it = ids.begin(); it != ids.end(); ++it )
00514     {
00515       PublicKey key(exportKey( *it, keyring ));
00516       keys.push_back(key);
00517       MIL << "Found key " << "[" << key.id() << "]" << " [" << key.name() << "]" << " [" << key.fingerprint() << "]" << endl;
00518     }
00519     return keys;
00520   }
00521 
00522   void KeyRing::Impl::importKey( const Pathname &keyfile, const Pathname &keyring)
00523   {
00524     if ( ! PathInfo(keyfile).isExist() )
00525       // TranslatorExplanation first %s is key name, second is keyring name
00526       ZYPP_THROW(KeyRingException(boost::str(boost::format(
00527           _("Tried to import not existant key %s into keyring %s"))
00528           % keyfile.asString() % keyring.asString())));
00529 
00530     const char* argv[] =
00531     {
00532       GPG_BINARY,
00533       "--no-default-keyring",
00534       "--quiet",
00535       "--no-tty",
00536       "--no-greeting",
00537       "--no-permission-warning",
00538       "--status-fd",
00539       "1",
00540       "--homedir",
00541       keyring.asString().c_str(),
00542       "--import",
00543       keyfile.asString().c_str(),
00544       NULL
00545     };
00546 
00547     int code;
00548     ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
00549     code = prog.close();
00550 
00551     //if ( code != 0 )
00552     //  ZYPP_THROW(Exception("failed to import key"));
00553   }
00554 
00555   void KeyRing::Impl::deleteKey( const string &id, const Pathname &keyring )
00556   {
00557     const char* argv[] =
00558     {
00559       GPG_BINARY,
00560       "--no-default-keyring",
00561       "--yes",
00562       "--quiet",
00563       "--no-tty",
00564       "--batch",
00565       "--status-fd",
00566       "1",
00567       "--homedir",
00568       keyring.asString().c_str(),
00569       "--delete-keys",
00570       id.c_str(),
00571       NULL
00572     };
00573 
00574     ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
00575 
00576     int code = prog.close();
00577     if ( code )
00578       ZYPP_THROW(Exception(_("Failed to delete key.")));
00579     else
00580       MIL << "Deleted key " << id << " from keyring " << keyring << endl;
00581   }
00582 
00583 
00584   string KeyRing::Impl::readSignatureKeyId(const Pathname &signature )
00585   {
00586     if ( ! PathInfo(signature).isFile() )
00587       ZYPP_THROW(Exception(boost::str(boost::format(
00588           _("Signature file %s not found"))% signature.asString())));
00589 
00590     MIL << "Determining key id if signature " << signature << endl;
00591     // HACK create a tmp keyring with no keys
00592     TmpDir dir(_base_dir, "fake-keyring");
00593 
00594     const char* argv[] =
00595     {
00596       GPG_BINARY,
00597       "--no-default-keyring",
00598       "--quiet",
00599       "--no-tty",
00600       "--no-greeting",
00601       "--batch",
00602       "--status-fd",
00603       "1",
00604       "--homedir",
00605       dir.path().asString().c_str(),
00606       signature.asString().c_str(),
00607       NULL
00608     };
00609 
00610     ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
00611 
00612     string line;
00613     int count = 0;
00614 
00615     str::regex rxNoKey("^\\[GNUPG:\\] NO_PUBKEY (.+)\n$");
00616     string id;
00617     for(line = prog.receiveLine(), count=0; !line.empty(); line = prog.receiveLine(), count++ )
00618     {
00619       //MIL << "[" << line << "]" << endl;
00620       str::smatch what;
00621       if(str::regex_match(line, what, rxNoKey))
00622       {
00623         if ( what.size() >= 1 )
00624           id = what[1];
00625         //dumpRegexpResults(what);
00626       }
00627       else
00628       {
00629         MIL << "'" << line << "'" << endl;
00630       }
00631     }
00632 
00633     if ( count == 0 )
00634     {
00635       MIL << "no output" << endl;
00636     }
00637 
00638     MIL << "Determined key id [" << id << "] for signature " << signature << endl;
00639     prog.close();
00640     return id;
00641   }
00642 
00643   bool KeyRing::Impl::verifyFile( const Pathname &file, const Pathname &signature, const Pathname &keyring)
00644   {
00645     const char* argv[] =
00646     {
00647       GPG_BINARY,
00648       "--no-default-keyring",
00649       "--quiet",
00650       "--no-tty",
00651       "--batch",
00652       "--no-greeting",
00653       "--status-fd",
00654       "1",
00655       "--homedir",
00656       keyring.asString().c_str(),
00657       "--verify",
00658       signature.asString().c_str(),
00659       file.asString().c_str(),
00660       NULL
00661     };
00662 
00663     // no need to parse output for now
00664     //     [GNUPG:] SIG_ID yCc4u223XRJnLnVAIllvYbUd8mQ 2006-03-29 1143618744
00665     //     [GNUPG:] GOODSIG A84EDAE89C800ACA SuSE Package Signing Key <build@suse.de>
00666     //     gpg: Good signature from "SuSE Package Signing Key <build@suse.de>"
00667     //     [GNUPG:] VALIDSIG 79C179B2E1C820C1890F9994A84EDAE89C800ACA 2006-03-29 1143618744 0 3 0 17 2 00 79C179B2E1C820C1890F9994A84EDAE89C800ACA
00668     //     [GNUPG:] TRUST_UNDEFINED
00669 
00670     //     [GNUPG:] ERRSIG A84EDAE89C800ACA 17 2 00 1143618744 9
00671     //     [GNUPG:] NO_PUBKEY A84EDAE89C800ACA
00672 
00673     ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
00674 
00675     return (prog.close() == 0) ? true : false;
00676   }
00677 
00679 
00681   //
00682   //    CLASS NAME : KeyRing
00683   //
00685 
00687   //
00688   //    METHOD NAME : KeyRing::KeyRing
00689   //    METHOD TYPE : Ctor
00690   //
00691   KeyRing::KeyRing(const Pathname &baseTmpDir)
00692   : _pimpl( new Impl(baseTmpDir) )
00693   {}
00694 
00696   //
00697   //    METHOD NAME : KeyRing::KeyRing
00698   //    METHOD TYPE : Ctor
00699   //
00700   //KeyRing::KeyRing( const Pathname &general_kr, const Pathname &trusted_kr )
00701   //: _pimpl( new Impl(general_kr, trusted_kr) )
00702   //{}
00703 
00705   //
00706   //    METHOD NAME : KeyRing::~KeyRing
00707   //    METHOD TYPE : Dtor
00708   //
00709   KeyRing::~KeyRing()
00710   {}
00711 
00713   //
00714   // Forward to implementation:
00715   //
00717 
00718 
00719   void KeyRing::importKey( const PublicKey &key, bool trusted )
00720   {
00721     _pimpl->importKey( key, trusted );
00722   }
00723 
00724   string KeyRing::readSignatureKeyId( const Pathname &signature )
00725   {
00726     return _pimpl->readSignatureKeyId(signature);
00727   }
00728 
00729   void KeyRing::deleteKey( const string &id, bool trusted )
00730   {
00731     _pimpl->deleteKey(id, trusted);
00732   }
00733 
00734   list<PublicKey> KeyRing::publicKeys()
00735   {
00736     return _pimpl->publicKeys();
00737   }
00738 
00739   list<PublicKey> KeyRing::trustedPublicKeys()
00740   {
00741     return _pimpl->trustedPublicKeys();
00742   }
00743 
00744   list<string> KeyRing::publicKeyIds()
00745   {
00746     return _pimpl->publicKeyIds();
00747   }
00748 
00749   list<string> KeyRing::trustedPublicKeyIds()
00750   {
00751     return _pimpl->trustedPublicKeyIds();
00752   }
00753 
00754   bool KeyRing::verifyFileSignatureWorkflow(
00755       const Pathname &file,
00756       const string filedesc,
00757       const Pathname &signature,
00758       const KeyContext &keycontext)
00759   {
00760     return _pimpl->verifyFileSignatureWorkflow(file, filedesc, signature, keycontext);
00761   }
00762 
00763   bool KeyRing::verifyFileSignature( const Pathname &file, const Pathname &signature)
00764   {
00765     return _pimpl->verifyFileSignature(file, signature);
00766   }
00767 
00768   bool KeyRing::verifyFileTrustedSignature( const Pathname &file, const Pathname &signature)
00769   {
00770     return _pimpl->verifyFileTrustedSignature(file, signature);
00771   }
00772 
00773   void KeyRing::dumpPublicKey( const string &id, bool trusted, ostream &stream )
00774   {
00775     _pimpl->dumpPublicKey( id, trusted, stream);
00776   }
00777 
00778   bool KeyRing::isKeyTrusted( const string &id )
00779   {
00780     return _pimpl->isKeyTrusted(id);
00781   }
00782 
00783   bool KeyRing::isKeyKnown( const string &id )
00784   {
00785     return _pimpl->isKeyKnown(id);
00786   }
00787 
00789 } // namespace zypp

doxygen