Imported Upstream version 17.6.4 upstream/17.6.4
authorDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 2 Sep 2019 07:16:21 +0000 (16:16 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 2 Sep 2019 07:16:21 +0000 (16:16 +0900)
VERSION.cmake
package/libzypp.changes
po/zh_CN.po
tests/lib/TestSetup.h
zypp/KeyRing.cc
zypp/KeyRing.h
zypp/RepoInfo.cc
zypp/RepoInfo.h
zypp/misc/CheckAccessDeleted.cc
zypp/repo/PackageProvider.cc

index f677953..80a3df7 100644 (file)
@@ -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)
 #=======
index 0577cd3..70a6780 100644 (file)
@@ -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
index ca3ae12..cf64cd6 100644 (file)
@@ -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 <pan93412@gmail.com>\n"
+"PO-Revision-Date: 2018-09-01 06:01+0000\n"
+"Last-Translator: H. Zeng <zhx@cnzhx.net>\n"
 "Language-Team: Chinese (China) "
 "<https://l10n.opensuse.org/projects/libzypp/master/zh_CN/>\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
index 61b83a2..1a24bc0 100644 (file)
@@ -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;
index 8cfd65a..51ebcd0 100644 (file)
@@ -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<KeyRingReport> 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: "<<id_r;
+      return false;
+    }
+
+    return true;
+  }
+
   std::list<PublicKey> KeyRing::Impl::publicKeys( const Pathname & keyring )
   {
     const std::list<PublicKeyData> & 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 ); }
 
index b94dd09..d230836 100644 (file)
@@ -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();
 
index c167ed3..bd9a3f6 100644 (file)
@@ -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;
index 85a3979..11f3f62 100644 (file)
@@ -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
index 435b7db..bfd6b19 100644 (file)
@@ -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
index 99039dd..f7f0089 100644 (file)
@@ -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<KeyRingReport> 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: "<<keyID;
-                  break;
-                }
               } else {
                 // we did not find any information about the key in the header
                 // this should never happen