18 #include <boost/format.hpp>
37 #undef ZYPP_BASE_LOGGER_LOGGROUP
38 #define ZYPP_BASE_LOGGER_LOGGROUP "zypp::KeyRing"
40 #define GPG_BINARY "/usr/bin/gpg2"
54 {
return _keyRingDefaultAccept; }
58 MIL <<
"Set new KeyRing::DefaultAccept: " << value_r << endl;
59 _keyRingDefaultAccept = value_r;
90 struct CachedPublicKeyData
92 const std::list<PublicKeyData> & operator()(
const Pathname & keyring_r )
const
93 {
return getData( keyring_r ); }
104 Cache(
const Cache & rhs ) {}
107 typedef std::map<Pathname,Cache> CacheMap;
109 const std::list<PublicKeyData> & getData(
const Pathname & keyring_r )
const
112 if ( ! cache._keyringP )
115 cache._keyringP.reset(
new WatchFile( keyring_r/
"pubring.gpg",
WatchFile::NO_INIT ) );
117 return getData( keyring_r, cache );
120 const std::list<PublicKeyData> & getData(
const Pathname & keyring_r, Cache & cache_r )
const
122 if ( cache_r._keyringP->hasChanged() )
127 "--list-public-keys",
128 "--homedir", keyring_r.c_str(),
129 "--no-default-keyring",
133 "--with-fingerprint",
142 PublicKeyScanner scanner;
144 for( std::string line = prog.receiveLine(); !line.empty(); line = prog.receiveLine() )
146 scanner.scan( line );
150 cache_r._data.swap( scanner._keys );
151 MIL <<
"Found keys: " << cache_r._data << endl;
153 return cache_r._data;
168 Impl(
const Pathname & baseTmpDir )
173 MIL <<
"Current KeyRing::DefaultAccept: " << _keyRingDefaultAccept << endl;
177 void multiKeyImport(
const Pathname & keyfile_r,
bool trusted_r =
false );
178 void deleteKey(
const std::string &
id,
bool trusted );
197 void dumpPublicKey(
const std::string &
id,
bool trusted, std::ostream & stream )
206 const Pathname & file,
207 const std::string & filedesc,
208 const Pathname & signature,
217 bool verifyFile(
const Pathname & file,
const Pathname & signature,
const Pathname & keyring );
218 void importKey(
const Pathname & keyfile,
const Pathname & keyring );
223 void dumpPublicKey(
const std::string &
id,
const Pathname & keyring, std::ostream & stream );
226 void deleteKey(
const std::string &
id,
const Pathname & keyring );
228 std::list<PublicKey>
publicKeys(
const Pathname & keyring);
265 rpmdbEmitSignal->trustedKeyAdded( key );
266 emitSignal->trustedKeyAdded( key );
272 importKey( keyfile_r, trusted_r ? trustedKeyRing() : generalKeyRing() );
281 key = exportKey(
id, trustedKeyRing() );
284 deleteKey(
id, trusted ? trustedKeyRing() : generalKeyRing() );
291 rpmdbEmitSignal->trustedKeyRemoved( key );
292 emitSignal->trustedKeyRemoved( key );
298 MIL <<
"Searching key [" <<
id <<
"] in keyring " << keyring << endl;
299 const std::list<PublicKeyData> & keys(
publicKeyData( keyring ) );
300 for_( it, keys.begin(), keys.end() )
302 if (
id == (*it).id() )
312 return PublicKey( dumpPublicKeyToTmp( keyData.
id(), keyring ), keyData );
319 return PublicKey( dumpPublicKeyToTmp( keyData.
id(), keyring ), keyData );
322 WAR <<
"No key " <<
id <<
" to export from " << keyring << endl;
334 "--homedir", keyring.asString().c_str(),
335 "--no-default-keyring",
339 "--no-permission-warning",
355 MIL <<
"Going to export key " <<
id <<
" from " << keyring <<
" to " << tmpFile.
path() << endl;
357 std::ofstream os( tmpFile.
path().
c_str() );
364 const Pathname & file,
365 const std::string & filedesc,
366 const Pathname & signature,
370 MIL <<
"Going to verify signature for " << filedesc <<
" ( " << file <<
" ) with " << signature << endl;
373 if( signature.empty() || (!PathInfo( signature ).isExist()) )
375 bool res = report->askUserToAcceptUnsignedFile( filedesc, context );
376 MIL <<
"User decision on unsigned file: " << res << endl;
384 PublicKeyData trustedKeyData( publicKeyExists(
id, trustedKeyRing() ) );
385 if ( trustedKeyData )
387 MIL <<
"Key is trusted: " << trustedKeyData << endl;
391 PublicKeyData generalKeyData( publicKeyExists(
id, generalKeyRing() ) );
392 if ( generalKeyData )
399 MIL <<
"Key was updated. Saving new version into trusted keyring: " << generalKeyData << endl;
400 importKey( exportKey( generalKeyData, generalKeyRing() ),
true );
406 if ( verifyFile( file, signature, trustedKeyRing() ) )
410 if ( ! trustedKeyData )
411 trustedKeyData = publicKeyExists(
id, trustedKeyRing() );
412 return report->askUserToAcceptVerificationFailed( filedesc, exportKey( trustedKeyData, trustedKeyRing() ), context );
417 PublicKeyData generalKeyData( publicKeyExists(
id, generalKeyRing() ) );
418 if ( generalKeyData )
420 PublicKey key( exportKey( generalKeyData, generalKeyRing() ) );
421 MIL <<
"Exported key " <<
id <<
" to " << key.
path() << endl;
422 MIL <<
"Key " <<
id <<
" " << key.
name() <<
" is not trusted" << endl;
429 MIL <<
"User wants to trust key " <<
id <<
" " << key.
name() << endl;
432 Pathname whichKeyring;
435 MIL <<
"User wants to import key " <<
id <<
" " << key.
name() << endl;
437 whichKeyring = trustedKeyRing();
440 whichKeyring = generalKeyRing();
443 if ( verifyFile( file, signature, whichKeyring ) )
445 MIL <<
"File signature is verified" << endl;
450 MIL <<
"File signature check fails" << endl;
451 if ( report->askUserToAcceptVerificationFailed( filedesc, key, context ) )
453 MIL <<
"User continues anyway." << endl;
458 MIL <<
"User does not want to continue" << endl;
465 MIL <<
"User does not want to trust key " <<
id <<
" " << key.
name() << endl;
472 MIL <<
"File [" << file <<
"] ( " << filedesc <<
" ) signed with unknown key [" <<
id <<
"]" << endl;
473 if ( report->askUserToAcceptUnknownKey( filedesc,
id, context ) )
475 MIL <<
"User wants to accept unknown key " <<
id << endl;
480 MIL <<
"User does not want to accept unknown key " <<
id << endl;
490 const std::list<PublicKeyData> & keys(
publicKeyData( keyring ) );
491 std::list<PublicKey> ret;
493 for_( it, keys.begin(), keys.end() )
495 PublicKey key( exportKey( *it, keyring ) );
496 ret.push_back( key );
497 MIL <<
"Found key " << key << endl;
504 if ( ! PathInfo( keyfile ).isExist() )
507 _(
"Tried to import not existent key %s into keyring %s"))
508 % keyfile.asString() % keyring.asString())));
514 "--homedir", keyring.asString().c_str(),
515 "--no-default-keyring",
519 "--no-permission-warning",
521 keyfile.asString().c_str(),
535 "--homedir", keyring.asString().c_str(),
536 "--no-default-keyring",
548 int code = prog.
close();
552 MIL <<
"Deleted key " <<
id <<
" from keyring " << keyring << endl;
558 if ( ! PathInfo( signature ).isFile() )
560 _(
"Signature file %s not found"))% signature.asString())));
562 MIL <<
"Determining key id if signature " << signature << endl;
570 "--no-default-keyring",
576 signature.asString().c_str(),
585 str::regex rxNoKey(
"^\\[GNUPG:\\] NO_PUBKEY (.+)\n$" );
593 if ( what.
size() >= 1 )
604 MIL <<
"no output" << endl;
607 MIL <<
"Determined key id [" <<
id <<
"] for signature " << signature << endl;
618 "--homedir", keyring.asString().c_str(),
619 "--no-default-keyring",
625 signature.asString().c_str(),
626 file.asString().c_str(),
642 return ( prog.
close() == 0 ) ?
true :
false;
662 {
_pimpl->importKey( key, trusted ); }
665 {
_pimpl->multiKeyImport( keyfile_r, trusted_r ); }
668 {
return _pimpl->readSignatureKeyId( signature ); }
671 {
_pimpl->deleteKey(
id, trusted ); }
674 {
return _pimpl->publicKeys(); }
677 {
return _pimpl->trustedPublicKeys(); }
680 {
return _pimpl->publicKeyData(); }
683 {
return _pimpl->trustedPublicKeyData(); }
686 const Pathname & file,
687 const std::string filedesc,
688 const Pathname & signature,
690 {
return _pimpl->verifyFileSignatureWorkflow( file, filedesc, signature, keycontext ); }
693 {
return _pimpl->verifyFileSignature( file, signature ); }
696 {
return _pimpl->verifyFileTrustedSignature( file, signature ); }
699 {
_pimpl->dumpPublicKey(
id, trusted, stream ); }
702 {
return _pimpl->exportPublicKey( keyData ); }
705 {
return _pimpl->exportTrustedPublicKey( keyData ); }
708 {
return _pimpl->isKeyTrusted(
id ); }
711 {
return _pimpl->isKeyKnown(
id ); }
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).
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.
std::list< PublicKey > trustedPublicKeys()
scoped_ptr< WatchFile > _keyringP
void importKey(const PublicKey &key, bool trusted=false)
#define _(MSG)
Return translated text.
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.
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).
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