Imported Upstream version 16.3.2
[platform/upstream/libzypp.git] / zypp / KeyRing.cc
index bdee10e..d6b8246 100644 (file)
@@ -15,8 +15,6 @@
 #include <cstdio>
 #include <unistd.h>
 
-#include <boost/format.hpp>
-
 #include "zypp/TmpPath.h"
 #include "zypp/ZYppFactory.h"
 #include "zypp/ZYpp.h"
@@ -37,6 +35,7 @@ using std::endl;
 #undef  ZYPP_BASE_LOGGER_LOGGROUP
 #define ZYPP_BASE_LOGGER_LOGGROUP "zypp::KeyRing"
 
+/** \todo Fix duplicate define in PublicKey/KeyRing */
 #define GPG_BINARY "/usr/bin/gpg2"
 
 ///////////////////////////////////////////////////////////////////
@@ -59,6 +58,9 @@ namespace zypp
     _keyRingDefaultAccept = value_r;
   }
 
+  void KeyRingReport::infoVerify( const std::string & file_r, const PublicKeyData & keyData_r, const KeyContext & keycontext )
+  {}
+
   bool KeyRingReport::askUserToAcceptUnsignedFile( const std::string & file, const KeyContext & keycontext )
   { return _keyRingDefaultAccept.testFlag( KeyRing::ACCEPT_UNSIGNED_FILE ); }
 
@@ -95,13 +97,32 @@ namespace zypp
     private:
       struct Cache
       {
-       scoped_ptr<WatchFile> _keyringP;
-       std::list<PublicKeyData> _data;
-
        // Empty copy ctor to allow insert into std::map as
        // scoped_ptr is noncopyable.
        Cache() {}
        Cache( const Cache & rhs ) {}
+
+       void assertCache( const Pathname & keyring_r )
+       {
+         // .kbx since gpg2-2.1
+         if ( !_keyringK )
+           _keyringK.reset( new WatchFile( keyring_r/"pubring.kbx", WatchFile::NO_INIT ) );
+         if ( !_keyringP )
+           _keyringP.reset( new WatchFile( keyring_r/"pubring.gpg", WatchFile::NO_INIT ) );
+       }
+
+       bool hasChanged() const
+       {
+         bool k = _keyringK->hasChanged();     // be sure both files are checked
+         bool p = _keyringP->hasChanged();
+         return k || p;
+       }
+
+       std::list<PublicKeyData> _data;
+
+      private:
+       scoped_ptr<WatchFile> _keyringK;
+       scoped_ptr<WatchFile> _keyringP;
       };
 
       typedef std::map<Pathname,Cache> CacheMap;
@@ -109,17 +130,14 @@ namespace zypp
       const std::list<PublicKeyData> & getData( const Pathname & keyring_r ) const
       {
        Cache & cache( _cacheMap[keyring_r] );
-       if ( ! cache._keyringP )
-       {
-         // init new cache entry
-         cache._keyringP.reset( new WatchFile( keyring_r/"pubring.gpg", WatchFile::NO_INIT ) );
-       }
+       // init new cache entry
+       cache.assertCache( keyring_r );
        return getData( keyring_r, cache );
       }
 
       const std::list<PublicKeyData> & getData( const Pathname & keyring_r, Cache & cache_r ) const
       {
-       if ( cache_r._keyringP->hasChanged() )
+       if ( cache_r.hasChanged() )
        {
          const char* argv[] =
          {
@@ -129,6 +147,7 @@ namespace zypp
            "--no-default-keyring",
            "--quiet",
            "--with-colons",
+           "--fixed-list-mode",
            "--with-fingerprint",
            "--with-sig-list",
            "--no-tty",
@@ -201,11 +220,7 @@ namespace zypp
     PublicKey exportTrustedPublicKey( const PublicKeyData & keyData )
     { return exportKey( keyData, trustedKeyRing() ); }
 
-    bool verifyFileSignatureWorkflow(
-        const Pathname & file,
-        const std::string & filedesc,
-        const Pathname & signature,
-        const KeyContext & keycontext = KeyContext());
+    bool verifyFileSignatureWorkflow( const Pathname & file, const std::string & filedesc, const Pathname & signature, bool & sigValid_r, const KeyContext & keycontext = KeyContext());
 
     bool verifyFileSignature( const Pathname & file, const Pathname & signature )
     { return verifyFile( file, signature, generalKeyRing() ); }
@@ -248,20 +263,6 @@ namespace zypp
      * \endcode
      */
     CachedPublicKeyData cachedPublicKeyData;
-
-  public:
-    /** Offer default Impl. */
-    static shared_ptr<Impl> nullimpl()
-    {
-      static shared_ptr<Impl> _nullimpl( new Impl( filesystem::TmpPath::defaultLocation() ) );
-      return _nullimpl;
-    }
-
-  private:
-    friend Impl * rwcowClone<Impl>( const Impl * rhs );
-    /** clone for RWCOW_pointer */
-    Impl * clone() const
-    { return new Impl( *this ); }
   };
   ///////////////////////////////////////////////////////////////////
 
@@ -373,12 +374,10 @@ namespace zypp
     return tmpFile;
   }
 
-  bool KeyRing::Impl::verifyFileSignatureWorkflow(
-      const Pathname & file,
-      const std::string & filedesc,
-      const Pathname & signature,
-      const KeyContext & context )
+  bool KeyRing::Impl::verifyFileSignatureWorkflow( const Pathname & file, const std::string & filedesc, const Pathname & signature, bool & sigValid_r, const KeyContext & context )
   {
+    sigValid_r = false;        // set true if signature is actually successfully validated!
+
     callback::SendReport<KeyRingReport> report;
     MIL << "Going to verify signature for " << filedesc << " ( " << file << " ) with " << signature << endl;
 
@@ -415,13 +414,17 @@ namespace zypp
        }
       }
 
+      if ( ! trustedKeyData )  // invalidated by previous import
+       trustedKeyData = publicKeyExists( id, trustedKeyRing() );
+      report->infoVerify( filedesc, trustedKeyData, context );
+
       // it exists, is trusted, does it validates?
       if ( verifyFile( file, signature, trustedKeyRing() ) )
-        return true;
+      {
+        return (sigValid_r=true);      // signature is actually successfully validated!
+      }
       else
       {
-       if ( ! trustedKeyData ) // invalidated by previous import
-         trustedKeyData = publicKeyExists( id, trustedKeyRing() );
         return report->askUserToAcceptVerificationFailed( filedesc, exportKey( trustedKeyData, trustedKeyRing() ), context );
       }
     }
@@ -456,7 +459,7 @@ namespace zypp
           if ( verifyFile( file, signature, whichKeyring ) )
           {
             MIL << "File signature is verified" << endl;
-            return true;
+           return (sigValid_r=true);   // signature is actually successfully validated!
           }
           else
           {
@@ -516,9 +519,9 @@ namespace zypp
   {
     if ( ! PathInfo( keyfile ).isExist() )
       // TranslatorExplanation first %s is key name, second is keyring name
-      ZYPP_THROW(KeyRingException(boost::str(boost::format(
-          _("Tried to import not existent key %s into keyring %s"))
-          % keyfile.asString() % keyring.asString())));
+      ZYPP_THROW(KeyRingException( str::Format(_("Tried to import not existent key %s into keyring %s"))
+                                  % keyfile.asString()
+                                  % keyring.asString() ));
 
     const char* argv[] =
     {
@@ -569,17 +572,17 @@ namespace zypp
   std::string KeyRing::Impl::readSignatureKeyId( const Pathname & signature )
   {
     if ( ! PathInfo( signature ).isFile() )
-      ZYPP_THROW(Exception(boost::str(boost::format(
-          _("Signature file %s not found"))% signature.asString())));
+      ZYPP_THROW(Exception( str::Format(_("Signature file %s not found")) % signature.asString() ));
 
     MIL << "Determining key id if signature " << signature << endl;
     // HACK create a tmp keyring with no keys
     filesystem::TmpDir dir( _base_dir, "fake-keyring" );
+    std::string tmppath( dir.path().asString() );
 
     const char* argv[] =
     {
       GPG_BINARY,
-      "--homedir", dir.path().asString().c_str(),
+      "--homedir", tmppath.c_str(),
       "--no-default-keyring",
       "--quiet",
       "--no-tty",
@@ -695,34 +698,11 @@ namespace zypp
   std::list<PublicKeyData> KeyRing::trustedPublicKeyData()
   { return _pimpl->trustedPublicKeyData(); }
 
-  std::list<std::string> KeyRing::publicKeyIds()       // deprecated: use publicKeyData
-  {
-    const std::list<PublicKeyData> & keys( publicKeyData() );
-    std::list<std::string> ret;
-    for_( it, keys.begin(), keys.end() )
-    {
-      ret.push_back( (*it).id() );
-    }
-    return ret;
-  }
-
-  std::list<std::string> KeyRing::trustedPublicKeyIds()        // deprecated: use trustedPublicKeyData
-  {
-    const std::list<PublicKeyData> & keys( trustedPublicKeyData() );
-    std::list<std::string> ret;
-    for_( it, keys.begin(), keys.end() )
-    {
-      ret.push_back( (*it).id() );
-    }
-    return ret;
-  }
+  bool KeyRing::verifyFileSignatureWorkflow( const Pathname & file, const std::string & filedesc, const Pathname & signature, bool & sigValid_r, const KeyContext & keycontext )
+  { return _pimpl->verifyFileSignatureWorkflow( file, filedesc, signature, sigValid_r, keycontext ); }
 
-  bool KeyRing::verifyFileSignatureWorkflow(
-      const Pathname & file,
-      const std::string filedesc,
-      const Pathname & signature,
-      const KeyContext & keycontext )
-  { return _pimpl->verifyFileSignatureWorkflow( file, filedesc, signature, keycontext ); }
+  bool KeyRing::verifyFileSignatureWorkflow( const Pathname & file, const std::string filedesc, const Pathname & signature, const KeyContext & keycontext )
+  { bool unused; return _pimpl->verifyFileSignatureWorkflow( file, filedesc, signature, unused, keycontext ); }
 
   bool KeyRing::verifyFileSignature( const Pathname & file, const Pathname & signature )
   { return _pimpl->verifyFileSignature( file, signature ); }