ref: refs/heads/SuSE-SLE-10-SP3-Branch
commit bd84e146b624b3e045279a52817505250ebbebff
Author: Michael Andres
Date: Thu Jun 26 10:32:40 2008 +0000
- Import newer gpg keys if a trusted key is updated
(bnc#393160)
---
VERSION | 4 +-
devel/devel.ma/GpgKeyz.cc | 132 +++++++++++++++++++++++++++++++
package/libzypp.changes | 34 +++++---
zypp/KeyRing.cc | 59 +++++++++-----
zypp/PublicKey.cc | 191 +++++++++++++++++++++++++++++++-------------
zypp/PublicKey.h | 61 ++++++++++-----
zypp/base/String.h | 68 ++++++++++++++++
zypp/target/rpm/RpmDb.cc | 62 ++++++++++++---
zypp/target/rpm/RpmDb.h | 10 ++-
9 files changed, 495 insertions(+), 126 deletions(-)
diff --git a/VERSION b/VERSION
index 805aa9b..c4c7376 100644
--- a/VERSION
+++ b/VERSION
@@ -46,8 +46,8 @@ dnl
dnl ==================================================
m4_define([LIBZYPP_MAJOR], [2])
dnl ==================================================
-m4_define([LIBZYPP_MINOR], [31])
+m4_define([LIBZYPP_MINOR], [32])
m4_define([LIBZYPP_COMPATMINOR], [15])
dnl ==================================================
-m4_define([LIBZYPP_PATCH], [335])
+m4_define([LIBZYPP_PATCH], [0])
dnl ==================================================
diff --git a/devel/devel.ma/GpgKeyz.cc b/devel/devel.ma/GpgKeyz.cc
new file mode 100644
index 0000000..afe9852
--- /dev/null
+++ b/devel/devel.ma/GpgKeyz.cc
@@ -0,0 +1,132 @@
+#include "Tools.h"
+#include <iostream>
+#include <fstream>
+#include <list>
+#include <map>
+#include <set>
+
+#include
+#include
+#include
+#include "zypp/base/Exception.h"
+#include "zypp/base/InputStream.h"
+#include "zypp/base/DefaultIntegral.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+using namespace std;
+using namespace zypp;
+
+///////////////////////////////////////////////////////////////////
+
+static const Pathname sysRoot( "/Local/ma/GPG" );
+
+///////////////////////////////////////////////////////////////////
+
+struct KeyRingSignalsReceive : public callback::ReceiveReport<KeyRingSignals>
+{
+ KeyRingSignalsReceive()
+ {
+ connect();
+ }
+ virtual void trustedKeyAdded( const KeyRing &/*keyring*/, const PublicKey &/*key*/ )
+ {
+ USR << endl;
+ }
+ virtual void trustedKeyRemoved( const KeyRing &/*keyring*/, const PublicKey &/*key*/ )
+ {
+ USR << endl;
+ }
+};
+
+///////////////////////////////////////////////////////////////////
+
+void ltrusted()
+{
+ list<PublicKey> trustedPublicKeys;
+ {
+ //zypp::base::LogControl::TmpLineWriter shutUp;
+ KeyRing_Ptr p( getZYpp()->keyRing() );
+ trustedPublicKeys = p->trustedPublicKeys();
+ }
+ USR << "Trusted Keys " << trustedPublicKeys.size() << endl;
+ for_( it, trustedPublicKeys.begin(), trustedPublicKeys.end() )
+ {
+ USR << *it << endl;
+ USR << " Creat: " << (*it).created() << endl;
+ USR << " Expir: " << (*it).expires() << endl;
+ }
+}
+
+///////////////////////////////////////////////////////////////////
+/******************************************************************
+**
+** FUNCTION NAME : main
+** FUNCTION TYPE : int
+*/
+int main( int argc, char * argv[] )
+{
+ INT << "===[START]==========================================" << endl;
+ --argc;
+ ++argv;
+ KeyRingSignalsReceive r;
+
+ Source_Ref a( createSource( "dir:///schnell/CD-ARCHIVE/11.0/GM/DVD/i386/DVD1", "fifi" ) );
+
+ if ( 1 )
+ {
+ //zypp::base::LogControl::TmpLineWriter shutUp;
+ getZYpp()->initTarget( sysRoot );
+ }
+
+ INT << "===[DONE]===========================================" << endl;
+ zypp::base::LogControl::TmpLineWriter shutUp;
+ return 0;
+}
+
+/******************************************************************
+**
+** FUNCTION NAME : main
+** FUNCTION TYPE : int
+*/
+int main2( int argc, char * argv[] )
+{
+ INT << "===[START]==========================================" << endl;
+ --argc;
+ ++argv;
+ KeyRingSignalsReceive r;
+
+
+ KeyRing_Ptr p( getZYpp()->keyRing() );
+
+ //PublicKey ka("/Local/ma/GPG/all-keys/build-9c800aca-40d8063e.asc");
+ PublicKey kb("/Local/ma/GPG/all-keys/build-9c800aca-481f343a.asc");
+
+ SEC << "============================================" << endl;
+ ltrusted();
+ //p->importKey( ka, true );
+ //ltrusted();
+ p->importKey( kb, true );
+ ltrusted();
+
+ SEC << "============================================" << endl;
+
+ if ( 1 )
+ {
+ zypp::base::LogControl::TmpLineWriter shutUp;
+ getZYpp()->initTarget( sysRoot );
+ }
+
+
+
+ INT << "===[DONE]===========================================" << endl;
+ zypp::base::LogControl::TmpLineWriter shutUp;
+ return 0;
+}
+
diff --git a/package/libzypp.changes b/package/libzypp.changes
index c2e5056..8edc7de 100644
--- a/package/libzypp.changes
+++ b/package/libzypp.changes
@@ -1,8 +1,16 @@
-------------------------------------------------------------------
+Thu Jun 26 12:26:11 CEST 2008 - ma@suse.de
+
+- Import newer gpg keys if a trusted key is updated
+ (bnc#393160)
+- revision 10466
+- version 2.32.0
+
+-------------------------------------------------------------------
Mon Jun 16 13:23:01 CEST 2008 - ma@suse.de
- Fix bug introduced in version 2.31.2: Rug tries to install
- all available kernel updates, not just the one given on the
+ all available kernel updates, not just the one given on the
commandline. (bnc #399320)
- version 2.31.335
- revision 10378
@@ -10,13 +18,13 @@ Mon Jun 16 13:23:01 CEST 2008 - ma@suse.de
-------------------------------------------------------------------
Fri Apr 18 18:54:50 CEST 2008 - schubi@suse.de
-- added translations
+- added translations
- version 2.31.334 (was a fault in the last commit)
-------------------------------------------------------------------
Wed Apr 16 12:15:16 CEST 2008 - dmacvicar@suse.de
-- add patch by aschnell. fix removing rpms with epoch
+- add patch by aschnell. fix removing rpms with epoch
(bnc #372323)
- version 2.31.3
@@ -51,7 +59,7 @@ Wed Apr 2 02:21:11 CEST 2008 - mauro@suse.de
Mon Mar 31 09:04:07 CEST 2008 - schubi@suse.de
- Added new translations
-- version 2.30.10
+- version 2.30.10
-------------------------------------------------------------------
Wed Mar 26 12:43:08 CET 2008 - jkupec@suse.cz
@@ -78,7 +86,7 @@ Mon Mar 17 17:24:11 CET 2008 - dmacvicar@suse.de
-------------------------------------------------------------------
Wed Feb 27 16:10:00 CET 2008 - ma@suse.de
-
+
- Fixed computation of install order. Take requirements of
an installed packages uninstall scripts into account, if
the package is updated. (#258682,bnc #270514)
@@ -104,16 +112,16 @@ Wed Jan 16 16:09:56 CET 2008 - jkupec@suse.cz
Wed Nov 28 12:13:48 CET 2007 - schubi@suse.de
- Checking the queue if an item will be deleted. If yes, the requirements
- are not needed anymore. Bug 326384
+ are not needed anymore. Bug 326384
- r 7952
-------------------------------------------------------------------
Thu Nov 22 14:12:38 CET 2007 - schubi@suse.de
-- If a to be remove resolvable is a kmp package ( includes modaliases
- in the FRESHENS/SUPPLEMENTS ) and the removed resolvable will be
- updated by a new, the solver checks, if old kmp modaliases are not
- supported by the new package anymore AND these old modaliases are
+- If a to be remove resolvable is a kmp package ( includes modaliases
+ in the FRESHENS/SUPPLEMENTS ) and the removed resolvable will be
+ updated by a new, the solver checks, if old kmp modaliases are not
+ supported by the new package anymore AND these old modaliases are
still needed by the system. --> report a problem if it is still needed
- r7893
- version 2.30.3
@@ -121,7 +129,7 @@ Thu Nov 22 14:12:38 CET 2007 - schubi@suse.de
-------------------------------------------------------------------
Wed Nov 21 14:02:46 CET 2007 - schubi@suse.de
-- Patterns, Packages are "present" although they are incomplete. So patterns
+- Patterns, Packages are "present" although they are incomplete. So patterns
behave the same way like packages do. Bug 289577
This change fixes Bug 331798 too.
- r7883
@@ -129,11 +137,11 @@ Wed Nov 21 14:02:46 CET 2007 - schubi@suse.de
-------------------------------------------------------------------
Wed Nov 21 13:23:37 CET 2007 - schubi@suse.de
-- QueuItemRequire: Filter out all provider which have worser architecture,
+- QueuItemRequire: Filter out all provider which have worser architecture,
are NOT noarch and have not the same name as the requirement. The
last one is needed for updating packages via patch/atoms.
Bug 328081
-- r7878
+- r7878
-------------------------------------------------------------------
Mon Nov 19 16:42:01 CET 2007 - ma@suse.de
diff --git a/zypp/KeyRing.cc b/zypp/KeyRing.cc
index a7382e9..c42bb93 100644
--- a/zypp/KeyRing.cc
+++ b/zypp/KeyRing.cc
@@ -75,10 +75,10 @@ namespace zypp
bool KeyRingReport::askUserToImportKey( const PublicKey &key)
{ return _keyRingDefaultAccept; }
-
+
bool KeyRingReport::askUserToAcceptVerificationFailed( const std::string &file, const PublicKey &key )
{ return _keyRingDefaultAccept; }
-
+
///////////////////////////////////////////////////////////////////
//
// CLASS NAME : KeyRing::Impl
@@ -107,12 +107,12 @@ namespace zypp
void importKey( const PublicKey &key, bool trusted = false);
void deleteKey( const std::string &id, bool trusted );
-
+
std::string readSignatureKeyId( const Pathname &signature );
-
+
bool isKeyTrusted( const std::string &id);
bool isKeyKnown( const std::string &id );
-
+
std::list<PublicKey> trustedPublicKeys();
std::list<PublicKey> publicKeys();
@@ -168,9 +168,11 @@ namespace zypp
void KeyRing::Impl::importKey( const PublicKey &key, bool trusted)
{
- callback::SendReport<KeyRingSignals> emitSignal;
-
importKey( key.path(), trusted ? trustedKeyRing() : generalKeyRing() );
+ if ( trusted )
+ {
+ callback::SendReport<KeyRingSignals>()->trustedKeyAdded( trustedKeyRing(), key );
+ }
}
void KeyRing::Impl::deleteKey( const std::string &id, bool trusted)
@@ -202,7 +204,7 @@ namespace zypp
{
return publicKeyExists( id, trustedKeyRing() );
}
-
+
bool KeyRing::Impl::isKeyKnown( const std::string &id )
{
if ( publicKeyExists( id, trustedKeyRing() ) )
@@ -210,7 +212,7 @@ namespace zypp
else
return publicKeyExists( id, generalKeyRing() );
}
-
+
bool KeyRing::Impl::publicKeyExists( std::string id, const Pathname &keyring)
{
MIL << "Searching key [" << id << "] in keyring " << keyring << std::endl;
@@ -222,13 +224,13 @@ namespace zypp
}
return false;
}
-
+
PublicKey KeyRing::Impl::exportKey( std::string id, const Pathname &keyring)
{
TmpFile tmp_file( _base_dir, "pubkey-"+id+"-" );
Pathname keyfile = tmp_file.path();
MIL << "Going to export key " << id << " from " << keyring << " to " << keyfile << endl;
-
+
try {
std::ofstream os(keyfile.asString().c_str());
dumpPublicKey( id, keyring, os );
@@ -252,7 +254,7 @@ namespace zypp
{
dumpPublicKey( id, ( trusted ? trustedKeyRing() : generalKeyRing() ), stream );
}
-
+
void KeyRing::Impl::dumpPublicKey( const std::string &id, const Pathname &keyring, std::ostream &stream )
{
const char* argv[] =
@@ -303,7 +305,20 @@ namespace zypp
if ( publicKeyExists( id, trustedKeyRing() ) )
{
PublicKey key = exportKey( id, trustedKeyRing() );
-
+
+ // lets look if there is an updated key in the
+ // general keyring
+ if ( publicKeyExists( id, generalKeyRing() ) )
+ {
+ PublicKey untkey = exportKey( id, generalKeyRing() );
+ if ( untkey.created() > key.created() )
+ {
+ MIL << "Key " << key << " was updated. Saving new version into trusted keyring." << endl;
+ importKey( untkey, true );
+ key = untkey;
+ }
+ }
+
MIL << "Key " << id << " " << key.name() << " is trusted" << std::endl;
// it exists, is trusted, does it validates?
if ( verifyFile( file, signature, trustedKeyRing() ) )
@@ -422,9 +437,9 @@ namespace zypp
if ( what[1] == "pub" )
{
id = what[5];
-
+
std::string line2;
- for(line2 = prog.receiveLine(); !line2.empty(); line2 = prog.receiveLine(), count++ )
+ for( line2 = prog.receiveLine(); !line2.empty(); line2 = prog.receiveLine(), count++ )
{
str::smatch what2;
if (str::regex_match(line2, what2, rxColonsFpr, str::match_extra))
@@ -446,12 +461,12 @@ namespace zypp
prog.close();
return keys;
}
-
+
void KeyRing::Impl::importKey( const Pathname &keyfile, const Pathname &keyring)
{
if ( ! PathInfo(keyfile).isExist() )
ZYPP_THROW(KeyRingException("Tried to import not existant key " + keyfile.asString() + " into keyring " + keyring.asString()));
-
+
const char* argv[] =
{
"gpg",
@@ -629,12 +644,12 @@ namespace zypp
//
///////////////////////////////////////////////////////////////////
-
+
void KeyRing::importKey( const PublicKey &key, bool trusted )
{
- _pimpl->importKey( key.path(), trusted );
+ _pimpl->importKey( key, trusted );
}
-
+
std::string KeyRing::readSignatureKeyId( const Pathname &signature )
{
return _pimpl->readSignatureKeyId(signature);
@@ -679,12 +694,12 @@ namespace zypp
{
return _pimpl->isKeyTrusted(id);
}
-
+
bool KeyRing::isKeyKnown( const std::string &id )
{
return _pimpl->isKeyTrusted(id);
}
-
+
/////////////////////////////////////////////////////////////////
} // namespace zypp
///////////////////////////////////////////////////////////////////
diff --git a/zypp/PublicKey.cc b/zypp/PublicKey.cc
index 04f8c53..964934e 100644
--- a/zypp/PublicKey.cc
+++ b/zypp/PublicKey.cc
@@ -10,21 +10,25 @@
*
*/
#include <iostream>
-//#include "zypp/base/Logger.h"
+#include <vector>
+#include "zypp/base/Logger.h"
+#include "zypp/base/Exception.h"
#include "zypp/base/String.h"
-#include "zypp/PublicKey.h"
+
#include "zypp/ExternalProgram.h"
+#include "zypp/PublicKey.h"
#include "zypp/TmpPath.h"
#include "zypp/PathInfo.h"
-#include "zypp/base/Exception.h"
-#include "zypp/base/Logger.h"
+#include "zypp/Date.h"
+
+//#include <ctime>
using std::endl;
///////////////////////////////////////////////////////////////////
namespace zypp
-{ /////////////////////////////////////////////////////////////////
+{ /////////////////////////////////////////////////////////////////
//
// CLASS NAME : PublicKey::Impl
//
@@ -39,7 +43,7 @@ namespace zypp
readFromFile(file);
MIL << "Done reading key" << std::endl;
}
-
+
public:
/** Offer default Impl. */
static shared_ptr<Impl> nullimpl()
@@ -48,51 +52,55 @@ namespace zypp
return _nullimpl;
}
-
+#warning FIX asString ====================================================================================
std::string asString() const
{
- return "[" + id() + "] [" + name() + "] [" + fingerprint() + "]";
+ return "[" + id() + "-" + str::hexstring(created(),8).substr(2) + "] [" + name() + "] [" + fingerprint() + "]";
}
-
+
std::string armoredData() const
{ return _data; }
-
+
std::string id() const
{ return _id; }
-
+
std::string name() const
{ return _name; }
-
+
std::string fingerprint() const
{ return _fingerprint; }
-
+
+ Date created() const
+ { return _created; }
+
+ Date expires() const
+ { return _expires; }
+
Pathname path() const
- {
+ {
return _data_file.path();
//return _data_file;
}
-
+
protected:
-
+
void readFromFile( const Pathname &keyfile)
{
+
PathInfo info(keyfile);
- MIL << "Reading pubkey from " << keyfile << " of size " << info.size() << " and sha1 " << filesystem::checksum(keyfile, "sha1")<< endl;
+ MIL << "Reading pubkey from " << keyfile << " of size " << info.size() << " and sha1 " << filesystem::checksum(keyfile, "sha1")<< endl;
if ( !info.isExist() )
ZYPP_THROW(Exception("Can't read public key from " + keyfile.asString() + ", file not found"));
-
+
if ( copy( keyfile, _data_file.path() ) != 0 )
ZYPP_THROW(Exception("Can't copy public key data from " + keyfile.asString() + " to " + _data_file.path().asString() ));
-
- filesystem::TmpDir dir;
-
const char* argv[] =
{
"gpg",
+ "-v",
"--no-default-keyring",
- "--homedir",
- dir.path().asString().c_str(),
+ "--fixed-list-mode",
"--with-fingerprint",
"--with-colons",
"--quiet",
@@ -104,47 +112,85 @@ namespace zypp
_data_file.path().asString().c_str(),
NULL
};
-
+
ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
-
+
std::string line;
- int count = 0;
-
- str::regex rxColons("^([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):\n$");
-
- // pub:-:1024:17:A84EDAE89C800ACA:2000-10-19:2008-06-21::-:SuSE Package Signing Key :
-
- for(line = prog.receiveLine(), count=0; !line.empty(); line = prog.receiveLine(), count++ )
+ bool sawpub = false;
+ bool sawsig = false;
+
+ // pub:-:1024:17:A84EDAE89C800ACA:971961473:1214043198::-:SuSE Package Signing Key :
+ // fpr:::::::::79C179B2E1C820C1890F9994A84EDAE89C800ACA:
+ // sig:::17:A84EDAE89C800ACA:1087899198:::::[selfsig]::13x:
+ // sig:::17:9E40E310000AABA4:980442706::::[User ID not found]:10x:
+ // sig:::1:77B2E6003D25D3D9:980443247::::[User ID not found]:10x:
+ // sub:-:2048:16:197448E88495160C:971961490:1214043258::: [expires: 2008-06-21]
+ // sig:::17:A84EDAE89C800ACA:1087899258:::::[keybind]::18x:
+
+ for ( line = prog.receiveLine(); !line.empty(); line = prog.receiveLine() )
{
- //MIL << "[" << line << "]" << std::endl;
- str::smatch what;
- if(str::regex_match(line, what, rxColons, str::match_extra))
+ // trim trailing NL.
+ if ( line.empty() )
+ continue;
+ if ( line[line.size()-1] == '\n' )
+ line.erase( line.size()-1 );
+
+ // split at ':'
+ std::vectorstd::string words;
+ str::splitFields( line, std::back_inserter(words), ":" );
+ if( words.empty() )
+ continue;
+
+ if ( words[0] == "pub" )
{
- if ( what[1] == "pub" )
- {
- _id = what[5];
- _name = what[10];
- //return key;
- }
- else if ( what[1] == "fpr" )
- {
- _fingerprint = what[10];
- }
- //dumpRegexpResults(what);
+ if ( sawpub )
+ continue;
+ sawpub = true;
+ // take default from pub
+ _id = words[4];
+ _name = words[9];
+ _created = Date(str::strtonumDate::ValueType(words[5]));
+ _expires = Date(str::strtonumDate::ValueType(words[6]));
+
+ }
+ else if ( words[0] == "sig" )
+ {
+ if ( sawsig || words[words.size()-2] != "13x" )
+ continue;
+ sawsig = true;
+ // update creation and expire dates from 1st signature type "13x"
+ if ( ! words[5].empty() )
+ _created = Date(str::strtonumDate::ValueType(words[5]));
+ if ( ! words[6].empty() )
+ _expires = Date(str::strtonumDate::ValueType(words[6]));
+ }
+ else if ( words[0] == "fpr" )
+ {
+ _fingerprint = words[9];
+ }
+ else if ( words[0] == "uid" )
+ {
+ if ( ! words[9].empty() )
+ _name = words[9];
}
}
prog.close();
-
- if (_id.size() == 0 )
- ZYPP_THROW(BadKeyException("File " + keyfile.asString() + " doesn't contain public key data" , keyfile));
+
+ if ( _id.size() == 0 )
+ ZYPP_THROW( BadKeyException( "File " + keyfile.asString() + " doesn't contain public key data" , keyfile ) );
+
+ //replace all escaped semicolon with real ':'
+ str::replace_all( _name, "\\x3a", ":" );
}
-
+
private:
std::string _id;
std::string _name;
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 );
@@ -165,7 +211,9 @@ namespace zypp
PublicKey::PublicKey( const Pathname &file )
: _pimpl( new Impl(file) )
- {}
+ {
+ MIL << *this << endl;
+ }
///////////////////////////////////////////////////////////////////
//
// METHOD NAME : PublicKey::~PublicKey
@@ -184,22 +232,51 @@ namespace zypp
{
return _pimpl->asString();
}
-
+
std::string PublicKey::armoredData() const
{ return _pimpl->armoredData(); }
-
+
std::string PublicKey::id() const
{ return _pimpl->id(); }
-
+
std::string PublicKey::name() const
{ return _pimpl->name(); }
-
+
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(); }
+ bool PublicKey::operator==( PublicKey b ) const
+ {
+ return( b.id() == id()
+ && b.fingerprint() == fingerprint()
+ && b.created() == created() );
+ }
+
+ bool PublicKey::operator==( std::string sid ) const
+ {
+ return sid == id();
+ }
+
+ std::ostream & dumpOn( std::ostream & str, const PublicKey & obj )
+ {
+ str << "[" << obj.name() << "]" << endl;
+ str << " fpr " << obj.fingerprint() << endl;
+ str << " id " << obj.id() << endl;
+ str << " cre " << obj.created() << endl;
+ str << " exp " << obj.expires() << endl;
+ str << "]";
+ return str;
+ }
+
/////////////////////////////////////////////////////////////////
} // namespace zypp
-///////////////////////////////////////////////////////////////////
\ No newline at end of file
+///////////////////////////////////////////////////////////////////
diff --git a/zypp/PublicKey.h b/zypp/PublicKey.h
index 3fc4124..79ba4b5 100644
--- a/zypp/PublicKey.h
+++ b/zypp/PublicKey.h
@@ -25,8 +25,11 @@
///////////////////////////////////////////////////////////////////
namespace zypp
{ /////////////////////////////////////////////////////////////////
-
-
+
+ /**
+ * Exception thrown when the supplied key is
+ * not a valid gpg key
+ */
class BadKeyException : public Exception
{
public:
@@ -36,10 +39,10 @@ namespace zypp
BadKeyException()
: Exception( "Bad Key Exception" )
{}
-
+
Pathname keyFile() const
{ return _keyfile; }
-
+
/** Ctor taking message.
* Use \ref ZYPP_THROW to throw exceptions.
*/
@@ -51,14 +54,18 @@ namespace zypp
private:
Pathname _keyfile;
};
-
-
+
+
+ // forward declaration of class Date
+ class Date;
+
///////////////////////////////////////////////////////////////////
//
// CLASS NAME : PublicKey
//
- /** Class that represent a GPG Public Key
- */
+ /**
+ * Class that represent a GPG Public Key
+ */
class PublicKey
{
friend std::ostream & operator<<( std::ostream & str, const PublicKey & obj );
@@ -69,29 +76,38 @@ namespace zypp
public:
PublicKey();
- /** Ctor
+ /** Ctor
* \throws when data does not make a key
*/
PublicKey(const Pathname &file);
-
+
~PublicKey();
-
+
bool isValid() const
{ return ( ! id().empty() && ! fingerprint().empty() && !path().empty() ); }
-
+
std::string asString() const;
std::string armoredData() const;
std::string id() const;
std::string name() const;
std::string fingerprint() const;
- Pathname path() const;
-
- bool operator==( PublicKey b )
- { return (b.id() == id()) && (b.fingerprint() == fingerprint() ); }
-
- bool operator==( std::string sid )
- { return sid == id(); }
-
+
+ /**
+ * 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;
+ bool operator==( std::string sid ) const;
+
private:
/** Pointer to implementation */
RWCOW_pointer<Impl> _pimpl;
@@ -102,7 +118,10 @@ namespace zypp
inline std::ostream & operator<<( std::ostream & str, const PublicKey & obj )
{ return str << obj.asString(); }
- /////////////////////////////////////////////////////////////////
+ /** \relates PublicKey Detailed stream output */
+ std::ostream & dumpOn( std::ostream & str, const PublicKey & obj );
+
+ /////////////////////////////////////////////////////////////////
} // namespace zypp
///////////////////////////////////////////////////////////////////
#endif // ZYPP_PUBLICKEY_H
diff --git a/zypp/base/String.h b/zypp/base/String.h
index fe5b6f3..6f0c672 100644
--- a/zypp/base/String.h
+++ b/zypp/base/String.h
@@ -222,6 +222,23 @@ namespace zypp
inline bool strToBool( const std::string & str, bool default_r )
{ return( default_r ? strToFalse( str ) : strToTrue( str ) ); }
//@}
+ ///////////////////////////////////////////////////////////////////
+
+ /**
+ * Looks for text in string and replaces it in place
+ *
+ * \note It only performs substtution in one pass
+ */
+ inline std::string & replace_all( std::string & str, const std::string & from, const std::string & to )
+ {
+ std::string::size_type pos = 0;
+ while( pos < str.length() && (pos = str.find( from, pos )) != std::string::npos )
+ {
+ str.replace( pos, from.size(), to );
+ pos += to.size();
+ }
+ return str;
+ }
///////////////////////////////////////////////////////////////////
/** \name Split. */
@@ -259,6 +276,57 @@ namespace zypp
}
return ret;
}
+
+ /** Split \a line_r into fields.
+ * Any single character in \a sepchars_r is treated as a
+ * field separator. The words are passed to OutputIterator
+ * \a result_r.
+ * \code
+ * "" -> words 0
+ * ":" -> words 2 |||
+ * "a" -> words 1 |a|
+ * ":a" -> words 2 ||a|
+ * "a:" -> words 2 |a||
+ * ":a:" -> words 3 ||a||
+ *
+ * \endcode
+ *
+ * \code
+ * std::vectorstd::string words;
+ * str::split( "some line", std::back_inserter(words) )
+ * \endcode
+ *
+ */
+ template<class _OutputIterator>
+ unsigned splitFields( const std::string & line_r,
+ _OutputIterator result_r,
+ const std::string & sepchars_r = ":" )
+ {
+ const char * beg = line_r.c_str();
+ const char * cur = beg;
+ unsigned ret = 0;
+ for ( beg = cur; *beg; beg = cur, ++result_r )
+ {
+ // skip non sepchars
+ while( *cur && !::strchr( sepchars_r.c_str(), *cur ) )
+ ++cur;
+ // build string
+ *result_r = std::string( beg, cur-beg );
+ ++ret;
+ // skip sepchar
+ if ( *cur )
+ {
+ ++cur;
+ if ( ! *cur ) // ending with sepchar
+ {
+ *result_r = std::string(); // add final empty field
+ ++ret;
+ break;
+ }
+ }
+ }
+ return ret;
+ }
//@}
///////////////////////////////////////////////////////////////////
diff --git a/zypp/target/rpm/RpmDb.cc b/zypp/target/rpm/RpmDb.cc
index f2717d4..97088f4 100644
--- a/zypp/target/rpm/RpmDb.cc
+++ b/zypp/target/rpm/RpmDb.cc
@@ -87,15 +87,23 @@ namespace zypp
disconnect();
}
- virtual void trustedKeyAdded( const KeyRing &keyring, const PublicKey &key )
+ virtual void trustedKeyAdded( const KeyRing &, const PublicKey &key )
{
- MIL << "trusted key added to zypp Keyring. Syncronizing keys with rpm keyring" << std::endl;
- _rpmdb.importZyppKeyRingTrustedKeys();
- _rpmdb.exportTrustedKeysInZyppKeyRing();
+ MIL << "Trusted key added to zypp Keyring. Importing" << endl;
+ // now import the key in rpm
+ try
+ {
+ _rpmdb.importPubkey( key );
+ }
+ catch (RpmException &e)
+ {
+ ERR << "Could not import key " << key.id() << " (" << key.name() << " from " << key.path() << " in rpm database" << endl;
+ }
}
- virtual void trustedKeyRemoved( const KeyRing &keyring, const PublicKey &key )
+ virtual void trustedKeyRemoved( const KeyRing &, const PublicKey &key )
{
+ ERR << "Can't remove key " << key << " from rpm database." << endl;
}
RpmDb &_rpmdb;
@@ -957,7 +965,7 @@ namespace zypp
// now import the key in rpm
try
{
- importPubkey((*it).path());
+ importPubkey(*it);
MIL << "Trusted key " << (*it).id() << " (" << (*it).name() << ") imported in rpm database." << std::endl;
}
catch (RpmException &e)
@@ -975,13 +983,47 @@ namespace zypp
// METHOD TYPE : PMError
//
void RpmDb::importPubkey( const Pathname & pubkey_r )
+ { importPubkey( PublicKey(pubkey_r) ); }
+
+ void RpmDb::importPubkey( const PublicKey & pubkey_r )
{
FAILIFNOTINITIALIZED;
+ // check if the key is already in the rpm database and just
+ // return if it does.
+ set<Edition> rpm_keys = pubkeyEditions();
+ string keyshortid = pubkey_r.id().substr(8,8);
+ MIL << "Comparing '" << keyshortid << "' to: ";
+ for ( set<Edition>::const_iterator it = rpm_keys.begin(); it != rpm_keys.end(); ++it)
+ {
+ string id = str::toUpper( (*it).version() );
+ MIL << ", '" << id << "'";
+ if ( id == keyshortid )
+ {
+ // they match id
+ // now check if timestamp is different
+ Date date = Date(str::strtonumDate::ValueType("0x" + (*it).release()));
+ if ( date == pubkey_r.created() )
+ {
+
+ MIL << endl << "Key " << pubkey_r << " is already in the rpm trusted keyring." << endl;
+ return;
+ }
+ else
+ {
+ MIL << endl << "Key " << pubkey_r << " has another version in keyring. ( " << date << " & " << pubkey_r.created() << ")" << endl;
+
+ }
+
+ }
+ }
+ // key does not exists, lets import it
+ MIL << endl;
+
RpmArgVec opts;
opts.push_back ( "--import" );
opts.push_back ( "--" );
- opts.push_back ( pubkey_r.asString().c_str() );
+ opts.push_back ( pubkey_r.path().asString().c_str() );
// don't call modifyDatabase because it would remove the old
// rpm3 database, if the current database is a temporary one.
@@ -1006,11 +1048,11 @@ namespace zypp
if ( rpm_status != 0 )
{
- ZYPP_THROW(RpmSubprocessException(string("Failed to import public key from file ") + pubkey_r.asString() + string(": rpm returned ") + str::numstring(rpm_status)));
+ ZYPP_THROW(RpmSubprocessException(string("Failed to import public key from file ") + pubkey_r.path().asString() + string(": rpm returned ") + str::numstring(rpm_status)));
}
else
{
- MIL << "Imported public key from file " << pubkey_r << endl;
+ MIL << "Imported public key from file " << pubkey_r.path() << endl;
}
}
@@ -1943,7 +1985,7 @@ namespace zypp
void RpmDb::removePackage( Package::constPtr package, unsigned flags )
{
// clear epoch, see bnc #372323
- Edition tmp(package->edition().version(), package->edition().release(), Edition::noepoch);
+ Edition tmp(package->edition().version(), package->edition().release(), Edition::noepoch);
return removePackage( package->name()
+ "-" + tmp.asString()
diff --git a/zypp/target/rpm/RpmDb.h b/zypp/target/rpm/RpmDb.h
index 7395eb3..9532d69 100644
--- a/zypp/target/rpm/RpmDb.h
+++ b/zypp/target/rpm/RpmDb.h
@@ -220,7 +220,15 @@ namespace zypp
**/
void importPubkey( const Pathname & pubkey_r );
- /**
+ /**
+ * Import ascii armored public key in file pubkey_r.
+ *
+ * \throws RpmException
+ *
+ **/
+ void importPubkey( const PublicKey & pubkey_r );
+
+ /**
* Return the long ids of all installed public keys.
**/
std::list<PublicKey> pubkeys() const;
--
To unsubscribe, e-mail: zypp-commit+unsubscribe@opensuse.org
For additional commands, e-mail: zypp-commit+help@opensuse.org