libzypp 8.13.6

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