From fff4d1c760a763536aada647c9a6e888c4382452 Mon Sep 17 00:00:00 2001 From: DongHun Kwak Date: Mon, 2 Sep 2019 16:16:21 +0900 Subject: [PATCH] Imported Upstream version 17.6.4 --- VERSION.cmake | 4 +- package/libzypp.changes | 8 ++ po/zh_CN.po | 6 +- tests/lib/TestSetup.h | 7 +- zypp/KeyRing.cc | 203 ++++++++++++++++++++++++++-------------- zypp/KeyRing.h | 6 ++ zypp/RepoInfo.cc | 5 +- zypp/RepoInfo.h | 2 +- zypp/misc/CheckAccessDeleted.cc | 4 +- zypp/repo/PackageProvider.cc | 39 +------- 10 files changed, 166 insertions(+), 118 deletions(-) diff --git a/VERSION.cmake b/VERSION.cmake index f677953..80a3df7 100644 --- a/VERSION.cmake +++ b/VERSION.cmake @@ -61,8 +61,8 @@ SET(LIBZYPP_MAJOR "17") SET(LIBZYPP_COMPATMINOR "2") SET(LIBZYPP_MINOR "6") -SET(LIBZYPP_PATCH "3") +SET(LIBZYPP_PATCH "4") # -# LAST RELEASED: 17.6.3 (2) +# LAST RELEASED: 17.6.4 (2) # (The number in parenthesis is LIBZYPP_COMPATMINOR) #======= diff --git a/package/libzypp.changes b/package/libzypp.changes index 0577cd3..70a6780 100644 --- a/package/libzypp.changes +++ b/package/libzypp.changes @@ -1,4 +1,12 @@ ------------------------------------------------------------------- +Thu Sep 6 12:16:25 CEST 2018 - ma@suse.de + +- Automatically fetch repository signing key from gpgkey url + (bsc#1088037) +- lsof: use '-K i' if lsof supports it (bsc#1099847,bsc#1036304) +- version 17.6.4 (2) + +------------------------------------------------------------------- Thu Aug 30 16:44:56 CEST 2018 - ma@suse.de - Check for not imported keys after multi key import from rpmdb diff --git a/po/zh_CN.po b/po/zh_CN.po index ca3ae12..cf64cd6 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -12,8 +12,8 @@ msgstr "" "Project-Id-Version: YaST (@memory@)\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-08-03 11:09+0200\n" -"PO-Revision-Date: 2018-08-13 18:01+0000\n" -"Last-Translator: Yi-Jyun Pan \n" +"PO-Revision-Date: 2018-09-01 06:01+0000\n" +"Last-Translator: H. Zeng \n" "Language-Team: Chinese (China) " "\n" "Language: zh_CN\n" @@ -4190,7 +4190,7 @@ msgstr "访问 '%s' 时超时。" #: zypp/media/MediaException.cc:195 #, c-format, boost-format msgid "Downloaded data exceeded the expected filesize '%s' of '%s'." -msgstr "下载到的数据超出了 '%2$s' 中预期的文件大小 ''%1$s'。" +msgstr "下载到的数据超出了 '%2$s' 中预期的文件大小 '%1$s'。" #: zypp/media/MediaException.cc:203 #, c-format, boost-format diff --git a/tests/lib/TestSetup.h b/tests/lib/TestSetup.h index 61b83a2..1a24bc0 100644 --- a/tests/lib/TestSetup.h +++ b/tests/lib/TestSetup.h @@ -92,7 +92,10 @@ class TestSetup { _ctor( rootdir_r, Arch_empty, options_r ); } ~TestSetup() - { USR << (_tmprootdir.path() == _rootdir ? "DELETE" : "KEEP") << " TESTSETUP below " << _rootdir << endl; } + { + USR << (_tmprootdir.path() == _rootdir ? "DELETE" : "KEEP") << " TESTSETUP below " << _rootdir << endl; + ZConfig::instance().setRepoManagerRoot( Pathname() ); + } public: /** Whether directory \a path_r contains a solver testcase. */ @@ -403,6 +406,8 @@ class TestSetup filesystem::clean_dir( _rootdir ); } + ZConfig::instance().setRepoManagerRoot( _rootdir ); + if ( ! sysarch_r.empty() ) ZConfig::instance().setSystemArchitecture( sysarch_r ); USR << "CREATED TESTSETUP below " << _rootdir << endl; diff --git a/zypp/KeyRing.cc b/zypp/KeyRing.cc index 8cfd65a..51ebcd0 100644 --- a/zypp/KeyRing.cc +++ b/zypp/KeyRing.cc @@ -233,6 +233,8 @@ namespace zypp PublicKeyData trustedPublicKeyExists( const std::string & id ) { return publicKeyExists(id, trustedKeyRing());} + bool provideAndImportKeyFromRepositoryWorkflow (const std::string &id_r , const RepoInfo &info_r ); + private: bool verifyFile( const Pathname & file, const Pathname & signature, const Pathname & keyring ); void importKey( const Pathname & keyfile, const Pathname & keyring ); @@ -425,103 +427,157 @@ namespace zypp // get the id of the signature (it might be a subkey id!) std::string id = readSignatureKeyId( signature ); - // does key exists in trusted keyring - PublicKeyData trustedKeyData( publicKeyExists( id, trustedKeyRing() ) ); - if ( trustedKeyData ) - { - MIL << "Key is trusted: " << trustedKeyData << endl; + PublicKeyData foundKey; + Pathname whichKeyring; - // lets look if there is an updated key in the - // general keyring - PublicKeyData generalKeyData( publicKeyExists( id, generalKeyRing() ) ); - if ( generalKeyData ) + if ( !id.empty() ) { + + // does key exists in trusted keyring + PublicKeyData trustedKeyData( publicKeyExists( id, trustedKeyRing() ) ); + if ( trustedKeyData ) { - // bnc #393160: Comment #30: Compare at least the fingerprint - // in case an attacker created a key the the same id. - // - // FIXME: bsc#1008325: For keys using subkeys, we'd actually need - // to compare the subkey sets, to tell whether a key was updated. - // because created() remains unchanged if the primary key is not touched. - // For now we wait until a new subkey signs the data and treat it as a - // new key (else part below). - if ( trustedKeyData.fingerprint() == generalKeyData.fingerprint() - && trustedKeyData.created() < generalKeyData.created() ) + MIL << "Key is trusted: " << trustedKeyData << endl; + + // lets look if there is an updated key in the + // general keyring + PublicKeyData generalKeyData( publicKeyExists( id, generalKeyRing() ) ); + if ( generalKeyData ) { - MIL << "Key was updated. Saving new version into trusted keyring: " << generalKeyData << endl; - importKey( exportKey( generalKeyData, generalKeyRing() ), true ); - trustedKeyData = publicKeyExists( id, trustedKeyRing() ); // re-read: invalidated by import? - } - } + // bnc #393160: Comment #30: Compare at least the fingerprint + // in case an attacker created a key the the same id. + // + // FIXME: bsc#1008325: For keys using subkeys, we'd actually need + // to compare the subkey sets, to tell whether a key was updated. + // because created() remains unchanged if the primary key is not touched. + // For now we wait until a new subkey signs the data and treat it as a + // new key (else part below). + if ( trustedKeyData.fingerprint() == generalKeyData.fingerprint() + && trustedKeyData.created() < generalKeyData.created() ) + { + MIL << "Key was updated. Saving new version into trusted keyring: " << generalKeyData << endl; + importKey( exportKey( generalKeyData, generalKeyRing() ), true ); + trustedKeyData = publicKeyExists( id, trustedKeyRing() ); // re-read: invalidated by import? + } + } - // it exists, is trusted, does it validate? - report->infoVerify( filedesc, trustedKeyData, context ); - if ( verifyFile( file, signature, trustedKeyRing() ) ) - { - return (sigValid_r=true); // signature is actually successfully validated! + foundKey = trustedKeyData; + whichKeyring = trustedKeyRing(); } else { - bool res = report->askUserToAcceptVerificationFailed( filedesc, exportKey( trustedKeyData, trustedKeyRing() ), context ); - MIL << "askUserToAcceptVerificationFailed: " << res << endl; - return res; - } - } - else - { - PublicKeyData generalKeyData( publicKeyExists( id, generalKeyRing() ) ); - if ( generalKeyData ) - { - PublicKey key( exportKey( generalKeyData, generalKeyRing() ) ); - MIL << "Key [" << id << "] " << key.name() << " is not trusted" << endl; - - // ok the key is not trusted, ask the user to trust it or not - KeyRingReport::KeyTrust reply = report->askUserToAcceptKey( key, context ); - if ( reply == KeyRingReport::KEY_TRUST_TEMPORARILY || - reply == KeyRingReport::KEY_TRUST_AND_IMPORT ) + PublicKeyData generalKeyData( publicKeyExists( id, generalKeyRing() ) ); + if ( generalKeyData ) { - MIL << "User wants to trust key [" << id << "] " << key.name() << endl; + PublicKey key( exportKey( generalKeyData, generalKeyRing() ) ); + MIL << "Key [" << id << "] " << key.name() << " is not trusted" << endl; - Pathname whichKeyring; - if ( reply == KeyRingReport::KEY_TRUST_AND_IMPORT ) + // ok the key is not trusted, ask the user to trust it or not + KeyRingReport::KeyTrust reply = report->askUserToAcceptKey( key, context ); + if ( reply == KeyRingReport::KEY_TRUST_TEMPORARILY || + reply == KeyRingReport::KEY_TRUST_AND_IMPORT ) { - MIL << "User wants to import key [" << id << "] " << key.name() << endl; - importKey( key, true ); - whichKeyring = trustedKeyRing(); - } - else - whichKeyring = generalKeyRing(); + MIL << "User wants to trust key [" << id << "] " << key.name() << endl; - // does it validate? - report->infoVerify( filedesc, generalKeyData, context ); - if ( verifyFile( file, signature, whichKeyring ) ) - { - return (sigValid_r=true); // signature is actually successfully validated! + if ( reply == KeyRingReport::KEY_TRUST_AND_IMPORT ) + { + MIL << "User wants to import key [" << id << "] " << key.name() << endl; + importKey( key, true ); + whichKeyring = trustedKeyRing(); + } + else + whichKeyring = generalKeyRing(); + + foundKey = generalKeyData; } else { - bool res = report->askUserToAcceptVerificationFailed( filedesc, key, context ); - MIL << "askUserToAcceptVerificationFailed: " << res << endl; - return res; + MIL << "User does not want to trust key [" << id << "] " << key.name() << endl; + return false; } } - else + else if ( ! context.empty() ) { - MIL << "User does not want to trust key [" << id << "] " << key.name() << endl; - return false; + // try to find the key in the repository info + if ( provideAndImportKeyFromRepositoryWorkflow( id, context.repoInfo() ) ) { + whichKeyring = trustedKeyRing(); + foundKey = PublicKeyData( publicKeyExists( id, trustedKeyRing() ) ); + } } } + } + + if ( foundKey ) { + // it exists, is trusted, does it validate? + report->infoVerify( filedesc, foundKey, context ); + if ( verifyFile( file, signature, whichKeyring ) ) + { + return (sigValid_r=true); // signature is actually successfully validated! + } else { - // signed with an unknown key... - MIL << "File [" << file << "] ( " << filedesc << " ) signed with unknown key [" << id << "]" << endl; - bool res = report->askUserToAcceptUnknownKey( filedesc, id, context ); - MIL << "askUserToAcceptUnknownKey: " << res << endl; - return res; + bool res = report->askUserToAcceptVerificationFailed( filedesc, exportKey( foundKey, whichKeyring ), context ); + MIL << "askUserToAcceptVerificationFailed: " << res << endl; + return res; } + } else { + // signed with an unknown key... + MIL << "File [" << file << "] ( " << filedesc << " ) signed with unknown key [" << id << "]" << endl; + bool res = report->askUserToAcceptUnknownKey( filedesc, id, context ); + MIL << "askUserToAcceptUnknownKey: " << res << endl; + return res; } + return false; } + bool KeyRing::Impl::provideAndImportKeyFromRepositoryWorkflow(const std::string &id_r, const RepoInfo &info_r) + { + if ( id_r.empty() ) + return false; + + const ZConfig &conf = ZConfig::instance(); + Pathname cacheDir = conf.repoManagerRoot() / conf.pubkeyCachePath(); + + Pathname myKey = info_r.provideKey( id_r, cacheDir ); + if ( myKey.empty() ) + // if we did not find any keys, there is no point in checking again, break + return false; + + callback::SendReport report; + + PublicKey key; + try { + key = PublicKey( myKey ); + } catch ( const Exception &e ) { + ZYPP_CAUGHT(e); + return false; + } + + if ( !key.isValid() ) { + ERR << "Key [" << id_r << "] from cache: " << cacheDir << " is not valid" << endl; + return false; + } + + MIL << "Key [" << id_r << "] " << key.name() << " loaded from cache" << endl; + + KeyContext context; + context.setRepoInfo( info_r ); + if ( ! report->askUserToAcceptPackageKey( key, context ) ) { + return false; + } + + MIL << "User wants to import key [" << id_r << "] " << key.name() << " from cache" << endl; + try { + importKey( key, true ); + } catch ( const KeyRingException &e ) { + ZYPP_CAUGHT(e); + ERR << "Failed to import key: "< KeyRing::Impl::publicKeys( const Pathname & keyring ) { const std::list & keys( publicKeyData( keyring ) ); @@ -656,6 +712,11 @@ namespace zypp bool KeyRing::verifyFileTrustedSignature( const Pathname & file, const Pathname & signature ) { return _pimpl->verifyFileTrustedSignature( file, signature ); } + bool KeyRing::provideAndImportKeyFromRepositoryWorkflow(const std::string &id, const RepoInfo &info) + { + return _pimpl->provideAndImportKeyFromRepositoryWorkflow( id, info ); + } + void KeyRing::dumpPublicKey( const std::string & id, bool trusted, std::ostream & stream ) { _pimpl->dumpPublicKey( id, trusted, stream ); } diff --git a/zypp/KeyRing.h b/zypp/KeyRing.h index b94dd09..d230836 100644 --- a/zypp/KeyRing.h +++ b/zypp/KeyRing.h @@ -321,6 +321,12 @@ namespace zypp bool verifyFileTrustedSignature( const Pathname &file, const Pathname &signature ); + /** + * Try to find the \a id in key cache or repository specified in \a info. Ask the user to trust + * the key if it was found + */ + bool provideAndImportKeyFromRepositoryWorkflow ( const std::string &id , const RepoInfo &info ); + /** Dtor */ ~KeyRing(); diff --git a/zypp/RepoInfo.cc b/zypp/RepoInfo.cc index c167ed3..bd9a3f6 100644 --- a/zypp/RepoInfo.cc +++ b/zypp/RepoInfo.cc @@ -501,8 +501,11 @@ namespace zypp _pimpl->gpgKeyUrls().raw().push_back( url_r ); } - Pathname RepoInfo::provideKey(const std::string &keyID_r, const Pathname &targetDirectory_r) + Pathname RepoInfo::provideKey(const std::string &keyID_r, const Pathname &targetDirectory_r) const { + if ( keyID_r.empty() ) + return Pathname(); + MIL << "Check for " << keyID_r << " at " << targetDirectory_r << endl; std::string keyIDStr( keyID_r.size() > 8 ? keyID_r.substr( keyID_r.size()-8 ) : keyID_r ); // print short ID in Jobreports filesystem::TmpDir tmpKeyRingDir; diff --git a/zypp/RepoInfo.h b/zypp/RepoInfo.h index 85a3979..11f3f62 100644 --- a/zypp/RepoInfo.h +++ b/zypp/RepoInfo.h @@ -401,7 +401,7 @@ namespace zypp void setGpgKeyUrl( const Url &gpgkey ); /** downloads all configured gpg keys into the defined directory */ - Pathname provideKey(const std::string &keyID_r, const Pathname &targetDirectory_r ); + Pathname provideKey(const std::string &keyID_r, const Pathname &targetDirectory_r ) const; /** * \short Whether packages downloaded from this repository will be kept in local cache diff --git a/zypp/misc/CheckAccessDeleted.cc b/zypp/misc/CheckAccessDeleted.cc index 435b7db..bfd6b19 100644 --- a/zypp/misc/CheckAccessDeleted.cc +++ b/zypp/misc/CheckAccessDeleted.cc @@ -78,6 +78,8 @@ namespace zypp /** bsc#1099847: Check for lsof version < 4.90 which does not support '-K i' * Just a quick check to allow code15 libzypp runnig in a code12 environment. + * bsc#1036304: '-K i' was backported to older lsof versions, indicated by + * lsof providing 'backported-option-Ki'. */ bool lsofNoOptKi() { @@ -95,7 +97,7 @@ namespace zypp } tmpUnblock; librpmDb::db_const_iterator it; - return( it.findPackage( "lsof" ) && it->tag_edition() < Edition("4.90") ); + return( it.findPackage( "lsof" ) && it->tag_edition() < Edition("4.90") && !it->tag_provides().count( Capability("backported-option-Ki") ) ); } } //namespace diff --git a/zypp/repo/PackageProvider.cc b/zypp/repo/PackageProvider.cc index 99039dd..f7f0089 100644 --- a/zypp/repo/PackageProvider.cc +++ b/zypp/repo/PackageProvider.cc @@ -234,46 +234,9 @@ namespace zypp std::string keyID = hr->signatureKeyID(); if ( keyID.length() > 0 ) { - const ZConfig &conf = ZConfig::instance(); - Pathname cacheDir = conf.repoManagerRoot() / conf.pubkeyCachePath(); - - Pathname myKey = info.provideKey ( keyID, cacheDir ); - if ( myKey.empty() ) - // if we did not find any keys, there is no point in checking again, break - break; - - callback::SendReport report; - - PublicKey key; - try { - key = PublicKey( myKey ); - } catch ( const Exception &e ) { - ZYPP_CAUGHT(e); - break; - } - - if ( !key.isValid() ) { - ERR << "Key [" << keyID << "] from cache: " << cacheDir << " is not valid" << endl; + if ( ! getZYpp()->keyRing()->provideAndImportKeyFromRepositoryWorkflow( keyID, info ) ) break; - } - - MIL << "Key [" << keyID << "] " << key.name() << " loaded from cache" << endl; - KeyContext context; - context.setRepoInfo( info ); - if ( ! report->askUserToAcceptPackageKey( key, context ) ) { - break; - } - - MIL << "User wants to import key [" << keyID << "] " << key.name() << " from cache" << endl; - KeyRing_Ptr theKeyRing = getZYpp()->keyRing(); - try { - theKeyRing->importKey( key, true ); - } catch ( const KeyRingException &e ) { - ZYPP_CAUGHT(e); - ERR << "Failed to import key: "<