36 #undef ZYPP_BASE_LOGGER_LOGGROUP 37 #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;
72 return KEY_TRUST_TEMPORARILY;
74 return KEY_TRUST_AND_IMPORT;
75 return KEY_DONT_TRUST;
93 struct CachedPublicKeyData
95 const std::list<PublicKeyData> & operator()(
const Pathname & keyring_r )
const 96 {
return getData( keyring_r ); }
104 Cache(
const Cache & rhs ) {}
106 void assertCache(
const Pathname & keyring_r )
115 bool hasChanged()
const 129 typedef std::map<Pathname,Cache> CacheMap;
131 const std::list<PublicKeyData> & getData(
const Pathname & keyring_r )
const 135 cache.assertCache( keyring_r );
136 return getData( keyring_r, cache );
139 const std::list<PublicKeyData> & getData(
const Pathname & keyring_r, Cache & cache_r )
const 141 if ( cache_r.hasChanged() )
146 "--list-public-keys",
147 "--homedir", keyring_r.c_str(),
148 "--no-default-keyring",
152 "--with-fingerprint",
161 PublicKeyScanner scanner;
163 for( std::string line = prog.receiveLine(); !line.empty(); line = prog.receiveLine() )
165 scanner.scan( line );
169 cache_r._data.swap( scanner._keys );
170 MIL <<
"Found keys: " << cache_r._data << endl;
172 return cache_r._data;
187 Impl(
const Pathname & baseTmpDir )
188 : _trusted_tmp_dir( baseTmpDir,
"zypp-trusted-kr" )
189 , _general_tmp_dir( baseTmpDir,
"zypp-general-kr" )
190 , _base_dir( baseTmpDir )
192 MIL <<
"Current KeyRing::DefaultAccept: " << _keyRingDefaultAccept << endl;
196 void multiKeyImport(
const Pathname & keyfile_r,
bool trusted_r =
false );
197 void deleteKey(
const std::string &
id,
bool trusted );
202 {
return bool(publicKeyExists(
id, trustedKeyRing() )); }
204 {
return publicKeyExists(
id, trustedKeyRing() ) || publicKeyExists(
id, generalKeyRing() ); }
216 void dumpPublicKey(
const std::string &
id,
bool trusted, std::ostream & stream )
217 {
dumpPublicKey(
id, ( trusted ? trustedKeyRing() : generalKeyRing() ), stream ); }
220 {
return exportKey( keyData, generalKeyRing() ); }
222 {
return exportKey( keyData, trustedKeyRing() ); }
227 {
return verifyFile( file, signature, generalKeyRing() ); }
229 {
return verifyFile( file, signature, trustedKeyRing() ); }
232 bool verifyFile(
const Pathname & file,
const Pathname & signature,
const Pathname & keyring );
233 void importKey(
const Pathname & keyfile,
const Pathname & keyring );
235 PublicKey exportKey(
const std::string &
id,
const Pathname & keyring );
238 void dumpPublicKey(
const std::string &
id,
const Pathname & keyring, std::ostream & stream );
239 filesystem::TmpFile dumpPublicKeyToTmp(
const std::string &
id,
const Pathname & keyring );
241 void deleteKey(
const std::string &
id,
const Pathname & keyring );
243 std::list<PublicKey>
publicKeys(
const Pathname & keyring);
245 {
return cachedPublicKeyData( keyring ); }
248 PublicKeyData publicKeyExists(
const std::string &
id,
const Pathname & keyring );
251 {
return _general_tmp_dir.path(); }
253 {
return _trusted_tmp_dir.path(); }
273 importKey( key.
path(), trusted ? trustedKeyRing() : generalKeyRing() );
278 rpmdbEmitSignal->trustedKeyAdded( key );
281 emitSignal->trustedKeyAdded( key );
285 ERR <<
"Could not import key " << excp << endl;
293 importKey( keyfile_r, trusted_r ? trustedKeyRing() : generalKeyRing() );
298 deleteKey(
id, trusted ? trustedKeyRing() : generalKeyRing() );
302 PublicKey key( exportKey(
id, trustedKeyRing() ) );
305 rpmdbEmitSignal->trustedKeyRemoved( key );
308 emitSignal->trustedKeyRemoved( key );
312 ERR <<
"Could not delete key " << excp << endl;
320 MIL <<
"Searching key [" <<
id <<
"] in keyring " << keyring << endl;
324 if ( key.providesKey(
id ) )
335 return PublicKey( dumpPublicKeyToTmp( keyData.
id(), keyring ), keyData );
342 return PublicKey( dumpPublicKeyToTmp( keyData.
id(), keyring ), keyData );
345 WAR <<
"No key " <<
id <<
" to export from " << keyring << endl;
357 "--homedir", keyring.asString().c_str(),
358 "--no-default-keyring",
362 "--no-permission-warning",
378 MIL <<
"Going to export key " <<
id <<
" from " << keyring <<
" to " << tmpFile.
path() << endl;
380 std::ofstream os( tmpFile.
path().
c_str() );
391 MIL <<
"Going to verify signature for " << filedesc <<
" ( " << file <<
" ) with " << signature << endl;
394 if( signature.empty() || (!PathInfo( signature ).isExist()) )
396 bool res = report->askUserToAcceptUnsignedFile( filedesc, context );
397 MIL <<
"askUserToAcceptUnsignedFile: " << res << endl;
405 PublicKeyData trustedKeyData( publicKeyExists(
id, trustedKeyRing() ) );
406 if ( trustedKeyData )
408 MIL <<
"Key is trusted: " << trustedKeyData << endl;
412 PublicKeyData generalKeyData( publicKeyExists(
id, generalKeyRing() ) );
413 if ( generalKeyData )
426 MIL <<
"Key was updated. Saving new version into trusted keyring: " << generalKeyData << endl;
427 importKey( exportKey( generalKeyData, generalKeyRing() ),
true );
428 trustedKeyData = publicKeyExists(
id, trustedKeyRing() );
433 report->infoVerify( filedesc, trustedKeyData, context );
434 if ( verifyFile( file, signature, trustedKeyRing() ) )
436 return (sigValid_r=
true);
440 bool res = report->askUserToAcceptVerificationFailed( filedesc, exportKey( trustedKeyData, trustedKeyRing() ), context );
441 MIL <<
"askUserToAcceptVerificationFailed: " << res << endl;
447 PublicKeyData generalKeyData( publicKeyExists(
id, generalKeyRing() ) );
448 if ( generalKeyData )
450 PublicKey key( exportKey( generalKeyData, generalKeyRing() ) );
451 MIL <<
"Exported key " <<
id <<
" to " << key.
path() << endl;
452 MIL <<
"Key " <<
id <<
" " << key.
name() <<
" is not trusted" << endl;
459 MIL <<
"User wants to trust key " <<
id <<
" " << key.
name() << endl;
461 Pathname whichKeyring;
464 MIL <<
"User wants to import key " <<
id <<
" " << key.
name() << endl;
466 whichKeyring = trustedKeyRing();
469 whichKeyring = generalKeyRing();
472 report->infoVerify( filedesc, generalKeyData, context );
473 if ( verifyFile( file, signature, whichKeyring ) )
475 return (sigValid_r=
true);
479 bool res = report->askUserToAcceptVerificationFailed( filedesc, key, context );
480 MIL <<
"askUserToAcceptVerificationFailed: " << res << endl;
486 MIL <<
"User does not want to trust key " <<
id <<
" " << key.
name() << endl;
493 MIL <<
"File [" << file <<
"] ( " << filedesc <<
" ) signed with unknown key [" <<
id <<
"]" << endl;
494 bool res = report->askUserToAcceptUnknownKey( filedesc,
id, context );
495 MIL <<
"askUserToAcceptUnknownKey: " << res << endl;
504 const std::list<PublicKeyData> & keys(
publicKeyData( keyring ) );
505 std::list<PublicKey> ret;
507 for_( it, keys.begin(), keys.end() )
509 PublicKey key( exportKey( *it, keyring ) );
510 ret.push_back( key );
511 MIL <<
"Found key " << key << endl;
518 if ( ! PathInfo( keyfile ).isExist() )
522 % keyring.asString() ));
528 "--homedir", keyring.asString().c_str(),
529 "--no-default-keyring",
533 "--no-permission-warning",
535 keyfile.asString().c_str(),
549 "--homedir", keyring.asString().c_str(),
550 "--no-default-keyring",
562 int code = prog.
close();
566 MIL <<
"Deleted key " <<
id <<
" from keyring " << keyring << endl;
571 if ( ! PathInfo( signature ).isFile() )
574 MIL <<
"Determining key id of signature " << signature << endl;
579 signature.asString().c_str(),
595 static const str::regex rxKeyId(
" keyid +([0-9A-Z]+)" );
602 MIL <<
"Determined key id [" <<
id <<
"] for signature " << signature << endl;
613 "--homedir", keyring.asString().c_str(),
614 "--no-default-keyring",
620 signature.asString().c_str(),
621 file.asString().c_str(),
637 return ( prog.
close() == 0 ) ?
true :
false;
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)
static bool error(const std::string &msg_r, const UserData &userData_r=UserData())
send error text
bool isKeyTrusted(const std::string &id)
#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.
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)
bool verifyFileSignatureWorkflow(const Pathname &file, const std::string &filedesc, const Pathname &signature, bool &sigValid_r, const KeyContext &keycontext=KeyContext())
Follows a signature verification interacting with the user.
#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).
Remember a files attributes to detect content changes.
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
bool verifyFileSignatureWorkflow(const Pathname &file, const std::string &filedesc, const Pathname &signature, bool &sigValid_r, const KeyContext &keycontext=KeyContext())
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
bool startsWith(const C_Str &str_r, const C_Str &prefix_r)
alias for hasPrefix
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
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()
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)
std::string asUserHistory() const
A single (multiline) string composed of asUserString and historyAsString.
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