merge lslezak keyring changes
authorDuncan Mac-Vicar P <dmacvicar@suse.de>
Wed, 6 Feb 2008 16:56:47 +0000 (16:56 +0000)
committerDuncan Mac-Vicar P <dmacvicar@suse.de>
Wed, 6 Feb 2008 16:56:47 +0000 (16:56 +0000)
package/libzypp.changes
zypp/KeyRing.cc
zypp/PublicKey.cc
zypp/PublicKey.h
zypp/target/rpm/RpmDb.cc
zypp/target/rpm/RpmDb.h

index 8a69cc8..002ee6d 100644 (file)
@@ -5,6 +5,13 @@ Wed Jan 23 11:16:50 CET 2008 - ma@suse.de
   text locale.
 
 -------------------------------------------------------------------
+Tue Jan 15 14:56:21 CET 2008 - lslezak@suse.cz
+
+- added RpmDb::removePubkey(), call it from
+  KeyRing::Impl::deleteKey() - remove the GPG key from RPM when it
+  is removed from the trusted keyring
+
+-------------------------------------------------------------------
 Tue Dec 18 12:28:22 CET 2007 - aschnell@suse.de
 
 - fixed password handling in URLs (bug #347273)
index 3094213..006107f 100644 (file)
@@ -176,7 +176,23 @@ namespace zypp
 
   void KeyRing::Impl::deleteKey( const string &id, bool trusted)
   {
+    PublicKey key;
+
+    if (trusted)
+    {
+       key = exportKey(id, trustedKeyRing());
+    }
+
     deleteKey( id, trusted ? trustedKeyRing() : generalKeyRing() );
+
+    if ( trusted )
+    {
+      callback::SendReport<target::rpm::KeyRingSignals> rpmdbEmitSignal;
+      callback::SendReport<KeyRingSignals> emitSignal;
+
+      rpmdbEmitSignal->trustedKeyRemoved( key );
+      emitSignal->trustedKeyRemoved( key );
+    }
   }
 
   list<PublicKey> KeyRing::Impl::publicKeys()
index da77013..c76ed33 100644 (file)
@@ -20,6 +20,9 @@
 #include "zypp/PathInfo.h"
 #include "zypp/base/Exception.h"
 #include "zypp/base/Logger.h"
+#include "zypp/Date.h"
+
+#include <ctime>
 
 using std::endl;
 
@@ -66,6 +69,12 @@ namespace zypp
     
     std::string fingerprint() const
     { return _fingerprint; }
+
+    Date created() const
+    { return _created; }
+
+    Date expires() const
+    { return _expires; }
     
     Pathname path() const
     { 
@@ -74,6 +83,38 @@ namespace zypp
     }
     
     protected:
+
+      // create Date from a string in format YYYY-MM-DD
+      Date createDate(const std::string &datestr)
+      {
+       // empty input
+       if (datestr.empty())
+       {
+           return Date();
+       }
+
+       tm date;
+
+       try
+       {
+           // set the date
+           date.tm_year = str::strtonum<int>(std::string(datestr, 0, 4)) - 1900; // years since 1900
+           date.tm_mon = str::strtonum<int>(std::string(datestr, 5, 2)) - 1;     // months since January
+           date.tm_mday = str::strtonum<int>(std::string(datestr, 9, 2));        // day
+       }
+       catch(...)
+       {
+           WAR << "Cannot parse date string: " << datestr << std::endl;
+           return Date();
+       }
+
+       // reset time (set 00:00:00)
+       date.tm_sec = date.tm_min = date.tm_hour = 0;
+
+       time_t time_epoch = ::mktime(&date);
+
+       return Date(time_epoch);
+     }
       
      void readFromFile( const Pathname &keyfile)
      {
@@ -125,6 +166,9 @@ namespace zypp
             {
               _id = what[5];
               _name = what[10];
+
+             _created = createDate(what[6]);
+             _expires = createDate(what[7]);
             //return key;
             }
             else if ( what[1] == "fpr" )
@@ -146,6 +190,8 @@ namespace zypp
     std::string _fingerprint;
     std::string _data;
     filesystem::TmpFile _data_file;
+    Date _created;
+    Date _expires;
     //Pathname _data_file;
   private:
     friend Impl * rwcowClone<Impl>( const Impl * rhs );
@@ -197,6 +243,12 @@ namespace zypp
     
   std::string PublicKey::fingerprint() const
   { return _pimpl->fingerprint(); }
+
+  Date PublicKey::created() const
+  { return _pimpl->created(); }
+
+  Date PublicKey::expires() const
+  { return _pimpl->expires(); }
   
   Pathname PublicKey::path() const
   { return _pimpl->path(); }
index c6e67af..92af3fe 100644 (file)
@@ -55,7 +55,10 @@ namespace zypp
       Pathname _keyfile;
   };
   
-  
+
+  // forward declaration of class Date  
+  class Date;
+
   ///////////////////////////////////////////////////////////////////
   //
   //   CLASS NAME : PublicKey
@@ -88,6 +91,18 @@ namespace zypp
     std::string id() const;
     std::string name() const;
     std::string fingerprint() const;
+
+    /**
+     * Date when the key was created (time is 00:00:00)
+     */    
+    Date created() const;
+
+    /**
+     * Date when the key expires (time is 00:00:00)
+     * If the key never expires the date is Date() (i.e. 0 seconds since the epoch (1.1.1970))
+     */
+    Date expires() const;
+
     Pathname path() const; 
     
     bool operator==( PublicKey b ) const;
index e44202e..692e0ec 100644 (file)
@@ -100,7 +100,19 @@ struct KeyRingSignalReceiver : callback::ReceiveReport<KeyRingSignals>
   }
 
   virtual void trustedKeyRemoved( const PublicKey &key  )
-  {}
+  {
+    MIL << "Trusted key removed from zypp Keyring. Removing..." << endl;
+
+    // remove the key from rpm
+    try
+    {
+      _rpmdb.removePubkey( key );
+    }
+    catch (RpmException &e)
+    {
+      ERR << "Could not remove key " << key.id() << " (" << key.name() << ") from rpm database" << endl;
+    }
+  }
 
   RpmDb &_rpmdb;
 };
@@ -1040,6 +1052,80 @@ void RpmDb::importPubkey( const PublicKey & pubkey_r )
 ///////////////////////////////////////////////////////////////////
 //
 //
+//     METHOD NAME : RpmDb::removePubkey
+//     METHOD TYPE : PMError
+//
+void RpmDb::removePubkey( const PublicKey & pubkey_r )
+{
+  FAILIFNOTINITIALIZED;
+
+  // check if the key is in the rpm database and just
+  // return if it does not.
+  set<Edition> rpm_keys = pubkeyEditions();
+
+  // search the key
+  set<Edition>::const_iterator found_edition = rpm_keys.end();
+
+  for ( set<Edition>::const_iterator it = rpm_keys.begin(); it != rpm_keys.end(); ++it)
+  {
+    string id = str::toUpper( (*it).version() );
+    string keyshortid = pubkey_r.id().substr(8,8);
+    MIL << "Comparing '" << id << "' to '" << keyshortid << "'" << endl;
+    if ( id == keyshortid )
+    {
+       found_edition = it;
+       break;
+    }
+  }
+
+  // the key does not exist, cannot be removed
+  if (found_edition == rpm_keys.end())
+  {
+      WAR << "Key " << pubkey_r.id() << " is not in rpm db" << endl;
+      return;
+  }
+
+  string rpm_name("gpg-pubkey-" + found_edition->asString());
+
+  RpmArgVec opts;
+  opts.push_back ( "-e" );
+  opts.push_back ( "--" );
+  opts.push_back ( rpm_name.c_str() );
+
+  // don't call modifyDatabase because it would remove the old
+  // rpm3 database, if the current database is a temporary one.
+  // But do invalidate packages list.
+  _packages._valid = false;
+  run_rpm( opts, ExternalProgram::Stderr_To_Stdout );
+
+  string line;
+  while ( systemReadLine( line ) )
+  {
+    if ( line.substr( 0, 6 ) == "error:" )
+    {
+      WAR << line << endl;
+    }
+    else
+    {
+      DBG << line << endl;
+    }
+  }
+
+  int rpm_status = systemStatus();
+
+  if ( rpm_status != 0 )
+  {
+    ZYPP_THROW(RpmSubprocessException(string("Failed to remove public key ") + pubkey_r.asString() + string(": rpm returned  ") + str::numstring(rpm_status)));
+  }
+  else
+  {
+    MIL << "Key " << pubkey_r << " has been removed from RPM trusted keyring" << endl;
+  }
+}
+
+///////////////////////////////////////////////////////////////////
+//
+//
 //     METHOD NAME : RpmDb::pubkeys
 //     METHOD TYPE : set<Edition>
 //
index 5ae6918..e95b516 100644 (file)
@@ -220,6 +220,14 @@ public:
   void importPubkey( const PublicKey & pubkey_r );
 
   /**
+   * Remove a public key from the rpm database
+   *
+   * \throws RpmException
+   *
+   **/
+  void removePubkey( const PublicKey & pubkey_r );
+
+  /**
    * Return the long ids of all installed public keys.
    **/
   std::list<PublicKey> pubkeys() const;