18 #include <boost/format.hpp>
37 #undef ZYPP_BASE_LOGGER_LOGGROUP
38 #define ZYPP_BASE_LOGGER_LOGGROUP "zypp::KeyRing"
41 #define GPG_BINARY "/usr/bin/gpg2"
55 {
return _keyRingDefaultAccept; }
59 MIL <<
"Set new KeyRing::DefaultAccept: " << value_r << endl;
60 _keyRingDefaultAccept = value_r;
94 struct CachedPublicKeyData
96 const std::list<PublicKeyData> & operator()(
const Pathname & keyring_r )
const
97 {
return getData( keyring_r ); }
105 Cache(
const Cache & rhs ) {}
107 void assertCache(
const Pathname & keyring_r )
116 bool hasChanged()
const
130 typedef std::map<Pathname,Cache> CacheMap;
132 const std::list<PublicKeyData> & getData(
const Pathname & keyring_r )
const
136 cache.assertCache( keyring_r );
137 return getData( keyring_r, cache );
140 const std::list<PublicKeyData> & getData(
const Pathname & keyring_r, Cache & cache_r )
const
142 if ( cache_r.hasChanged() )
147 "--list-public-keys",
148 "--homedir", keyring_r.c_str(),
149 "--no-default-keyring",
153 "--with-fingerprint",
162 PublicKeyScanner scanner;
164 for( std::string line = prog.receiveLine(); !line.empty(); line = prog.receiveLine() )
166 scanner.scan( line );
170 cache_r._data.swap( scanner._keys );
171 MIL <<
"Found keys: " << cache_r._data << endl;
173 return cache_r._data;
188 Impl(
const Pathname & baseTmpDir )
193 MIL <<
"Current KeyRing::DefaultAccept: " << _keyRingDefaultAccept << endl;
197 void multiKeyImport(
const Pathname & keyfile_r,
bool trusted_r =
false );
198 void deleteKey(
const std::string &
id,
bool trusted );
217 void dumpPublicKey(
const std::string &
id,
bool trusted, std::ostream & stream )
226 const Pathname & file,
227 const std::string & filedesc,
228 const Pathname & signature,
237 bool verifyFile(
const Pathname & file,
const Pathname & signature,
const Pathname & keyring );
238 void importKey(
const Pathname & keyfile,
const Pathname & keyring );
243 void dumpPublicKey(
const std::string &
id,
const Pathname & keyring, std::ostream & stream );
246 void deleteKey(
const std::string &
id,
const Pathname & keyring );
248 std::list<PublicKey>
publicKeys(
const Pathname & keyring);
285 rpmdbEmitSignal->trustedKeyAdded( key );
286 emitSignal->trustedKeyAdded( key );
292 importKey( keyfile_r, trusted_r ? trustedKeyRing() : generalKeyRing() );
301 key = exportKey(
id, trustedKeyRing() );
304 deleteKey(
id, trusted ? trustedKeyRing() : generalKeyRing() );
311 rpmdbEmitSignal->trustedKeyRemoved( key );
312 emitSignal->trustedKeyRemoved( key );
318 MIL <<
"Searching key [" <<
id <<
"] in keyring " << keyring << endl;
319 const std::list<PublicKeyData> & keys(
publicKeyData( keyring ) );
320 for_( it, keys.begin(), keys.end() )
322 if (
id == (*it).id() )
332 return PublicKey( dumpPublicKeyToTmp( keyData.
id(), keyring ), keyData );
339 return PublicKey( dumpPublicKeyToTmp( keyData.
id(), keyring ), keyData );
342 WAR <<
"No key " <<
id <<
" to export from " << keyring << endl;
354 "--homedir", keyring.asString().c_str(),
355 "--no-default-keyring",
359 "--no-permission-warning",
375 MIL <<
"Going to export key " <<
id <<
" from " << keyring <<
" to " << tmpFile.
path() << endl;
377 std::ofstream os( tmpFile.
path().
c_str() );
384 const Pathname & file,
385 const std::string & filedesc,
386 const Pathname & signature,
390 MIL <<
"Going to verify signature for " << filedesc <<
" ( " << file <<
" ) with " << signature << endl;
393 if( signature.empty() || (!PathInfo( signature ).isExist()) )
395 bool res = report->askUserToAcceptUnsignedFile( filedesc, context );
396 MIL <<
"User decision on unsigned file: " << res << endl;
404 PublicKeyData trustedKeyData( publicKeyExists(
id, trustedKeyRing() ) );
405 if ( trustedKeyData )
407 MIL <<
"Key is trusted: " << trustedKeyData << endl;
411 PublicKeyData generalKeyData( publicKeyExists(
id, generalKeyRing() ) );
412 if ( generalKeyData )
419 MIL <<
"Key was updated. Saving new version into trusted keyring: " << generalKeyData << endl;
420 importKey( exportKey( generalKeyData, generalKeyRing() ),
true );
425 if ( ! trustedKeyData )
426 trustedKeyData = publicKeyExists(
id, trustedKeyRing() );
427 report->infoVerify( filedesc, trustedKeyData, context );
430 if ( verifyFile( file, signature, trustedKeyRing() ) )
434 return report->askUserToAcceptVerificationFailed( filedesc, exportKey( trustedKeyData, trustedKeyRing() ), context );
439 PublicKeyData generalKeyData( publicKeyExists(
id, generalKeyRing() ) );
440 if ( generalKeyData )
442 PublicKey key( exportKey( generalKeyData, generalKeyRing() ) );
443 MIL <<
"Exported key " <<
id <<
" to " << key.
path() << endl;
444 MIL <<
"Key " <<
id <<
" " << key.
name() <<
" is not trusted" << endl;
451 MIL <<
"User wants to trust key " <<
id <<
" " << key.
name() << endl;
454 Pathname whichKeyring;
457 MIL <<
"User wants to import key " <<
id <<
" " << key.
name() << endl;
459 whichKeyring = trustedKeyRing();
462 whichKeyring = generalKeyRing();
465 if ( verifyFile( file, signature, whichKeyring ) )
467 MIL <<
"File signature is verified" << endl;
472 MIL <<
"File signature check fails" << endl;
473 if ( report->askUserToAcceptVerificationFailed( filedesc, key, context ) )
475 MIL <<
"User continues anyway." << endl;
480 MIL <<
"User does not want to continue" << endl;
487 MIL <<
"User does not want to trust key " <<
id <<
" " << key.
name() << endl;
494 MIL <<
"File [" << file <<
"] ( " << filedesc <<
" ) signed with unknown key [" <<
id <<
"]" << endl;
495 if ( report->askUserToAcceptUnknownKey( filedesc,
id, context ) )
497 MIL <<
"User wants to accept unknown key " <<
id << endl;
502 MIL <<
"User does not want to accept unknown key " <<
id << endl;
512 const std::list<PublicKeyData> & keys(
publicKeyData( keyring ) );
513 std::list<PublicKey> ret;
515 for_( it, keys.begin(), keys.end() )
517 PublicKey key( exportKey( *it, keyring ) );
518 ret.push_back( key );
519 MIL <<
"Found key " << key << endl;
526 if ( ! PathInfo( keyfile ).isExist() )
529 _(
"Tried to import not existent key %s into keyring %s"))
530 % keyfile.asString() % keyring.asString())));
536 "--homedir", keyring.asString().c_str(),
537 "--no-default-keyring",
541 "--no-permission-warning",
543 keyfile.asString().c_str(),
557 "--homedir", keyring.asString().c_str(),
558 "--no-default-keyring",
570 int code = prog.
close();
574 MIL <<
"Deleted key " <<
id <<
" from keyring " << keyring << endl;
580 if ( ! PathInfo( signature ).isFile() )
582 _(
"Signature file %s not found"))% signature.asString())));
584 MIL <<
"Determining key id if signature " << signature << endl;
592 "--no-default-keyring",
598 signature.asString().c_str(),
607 str::regex rxNoKey(
"^\\[GNUPG:\\] NO_PUBKEY (.+)\n$" );
615 if ( what.
size() >= 1 )
626 MIL <<
"no output" << endl;
629 MIL <<
"Determined key id [" <<
id <<
"] for signature " << signature << endl;
640 "--homedir", keyring.asString().c_str(),
641 "--no-default-keyring",
647 signature.asString().c_str(),
648 file.asString().c_str(),
664 return ( prog.
close() == 0 ) ?
true :
false;
708 const Pathname & file,
709 const std::string filedesc,
710 const Pathname & signature,
void importKey(const PublicKey &key, bool trusted=false)
imports a key from a file.
const std::list< PublicKeyData > & publicKeyData()
PublicKey exportTrustedPublicKey(const PublicKeyData &keyData)
Export a trusted public key identified by its key data.
PublicKey exportPublicKey(const PublicKeyData &keyData)
const Pathname trustedKeyRing() const
void dumpPublicKey(const std::string &id, bool trusted, std::ostream &stream)
void deleteKey(const std::string &id, bool trusted)
PublicKey exportKey(const std::string &id, const Pathname &keyring)
bool isKeyTrusted(const std::string &id)
bool verifyFileSignatureWorkflow(const Pathname &file, const std::string filedesc, const Pathname &signature, const KeyContext &keycontext=KeyContext())
Follows a signature verification interacting with the user.
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
const std::list< PublicKeyData > & trustedPublicKeyData()
This basically means, we knew the key, but it was not trusted.
PublicKey exportPublicKey(const PublicKeyData &keyData)
Export a public key identified by its key data.
Class representing one GPG Public Keys data.
const std::string & asString() const
String representation.
bool isKeyKnown(const std::string &id)
void dumpPublicKey(const std::string &id, bool trusted, std::ostream &stream)
PublicKeyData publicKeyExists(const std::string &id, const Pathname &keyring)
Get PublicKeyData for ID (false if ID is not found).
void multiKeyImport(const Pathname &keyfile_r, bool trusted_r=false)
std::list< PublicKey > trustedPublicKeys()
Get a list of trusted public keys in the keyring (incl.
bool verifyFile(const Pathname &file, const Pathname &signature, const Pathname &keyring)
virtual bool askUserToAcceptUnsignedFile(const std::string &file, const KeyContext &keycontext=KeyContext())
KeyRing(const Pathname &baseTmpDir)
Default ctor.
std::list< PublicKeyData > trustedPublicKeyData()
Get a list of trusted public key data in the keyring (key data only)
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Provide a new empty temporary file and delete it when no longer needed.
virtual bool askUserToAcceptUnknownKey(const std::string &file, const std::string &id, const KeyContext &keycontext=KeyContext())
we DONT know the key, only its id, but we have never seen it, the difference with trust key is that i...
CachedPublicKeyData cachedPublicKeyData
Functor returning the keyrings data (cached).
virtual void infoVerify(const std::string &file_r, const PublicKeyData &keyData_r, const KeyContext &keycontext=KeyContext())
Informal callback showing the trusted key that will be used for verification.
PublicKey exportTrustedPublicKey(const PublicKeyData &keyData)
KeyTrust
User reply options for the askUserToTrustKey callback.
Pathname path() const
File containig the ASCII armored key.
static void setDefaultAccept(DefaultAccept value_r)
Set the active accept bits.
Provide a new empty temporary directory and recursively delete it when no longer needed.
filesystem::TmpDir _trusted_tmp_dir
bool verifyFileSignature(const Pathname &file, const Pathname &signature)
Execute a program and give access to its io An object of this class encapsulates the execution of an ...
std::list< PublicKeyData > _data
filesystem::TmpFile dumpPublicKeyToTmp(const std::string &id, const Pathname &keyring)
const char * c_str() const
String representation.
std::string fingerprint() const
Key fingerprint.
IMPL_PTR_TYPE(Application)
std::list< PublicKey > trustedPublicKeys()
scoped_ptr< WatchFile > _keyringP
void importKey(const PublicKey &key, bool trusted=false)
std::string receiveLine()
Read one line from the input stream.
Impl(const Pathname &baseTmpDir)
bool isKeyKnown(const std::string &id)
true if the key id is knows, that means at least exist on the untrusted keyring
void multiKeyImport(const Pathname &keyfile_r, bool trusted_r=false)
Initial import from RpmDb.
const Pathname generalKeyRing() const
User has chosen not to trust the key.
int close()
Wait for the progamm to complete.
virtual KeyTrust askUserToAcceptKey(const PublicKey &key, const KeyContext &keycontext=KeyContext())
Ask user to trust and/or import the key to trusted keyring.
scoped_ptr< WatchFile > _keyringK
static DefaultAccept defaultAccept()
Get the active accept bits.
RW_pointer< Impl > _pimpl
Pointer to implementation.
Regular expression match result.
Class representing one GPG Public Key (PublicKeyData + ASCII armored in a tempfile).
std::list< PublicKeyData > publicKeyData()
Get a list of public key data in the keyring (key data only)
Base class for Exception.
std::list< PublicKey > publicKeys()
bool verifyFileSignatureWorkflow(const Pathname &file, const std::string &filedesc, const Pathname &signature, const KeyContext &keycontext=KeyContext())
std::string id() const
Key ID.
void deleteKey(const std::string &id, bool trusted=false)
removes a key from the keyring.
bool verifyFileTrustedSignature(const Pathname &file, const Pathname &signature)
bool verifyFileTrustedSignature(const Pathname &file, const Pathname &signature)
bool regex_match(const std::string &s, smatch &matches, const regex ®ex)
regex ZYPP_STR_REGEX regex ZYPP_STR_REGEX
const std::list< PublicKeyData > & publicKeyData(const Pathname &keyring)
bool isKeyTrusted(const std::string &id)
true if the key id is trusted
Date created() const
Creation / last modification date (latest selfsig).
Easy-to use interface to the ZYPP dependency resolver.
std::string readSignatureKeyId(const Pathname &signature)
reads the public key id from a signature
bool verifyFileSignature(const Pathname &file, const Pathname &signature)
Verifies a file against a signature, with no user interaction.
std::string readSignatureKeyId(const Pathname &signature)
virtual bool askUserToAcceptVerificationFailed(const std::string &file, const PublicKey &key, const KeyContext &keycontext=KeyContext())
The file filedesc is signed but the verification failed.
std::list< PublicKey > publicKeys()
Get a list of public keys in the keyring (incl.
filesystem::TmpDir _general_tmp_dir