1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/KeyRing.cc
14 //#include "zypp/base/Logger.h"
19 #include "zypp/ZYppFactory.h"
20 #include "zypp/ZYpp.h"
22 #include <boost/regex.hpp>
24 #include "zypp/base/String.h"
25 #include "zypp/KeyRing.h"
26 #include "zypp/ExternalProgram.h"
27 #include "zypp/TmpPath.h"
30 using namespace boost;
31 using namespace zypp::filesystem;
34 ///////////////////////////////////////////////////////////////////
36 { /////////////////////////////////////////////////////////////////
38 IMPL_PTR_TYPE(KeyRing);
40 static void dumpRegexpResults( const boost::smatch &what )
42 for ( unsigned int k=0; k < what.size(); k++)
44 XXX << "[match "<< k << "] [" << what[k] << "]" << std::endl;
48 ///////////////////////////////////////////////////////////////////
50 // CLASS NAME : KeyRing::Impl
52 /** KeyRing implementation. */
58 Impl( const Pathname &general_kr, const Pathname &trusted_kr )
60 filesystem::assert_dir(general_kr);
61 filesystem::assert_dir(trusted_kr);
63 _general_kr = general_kr;
64 _trusted_kr = trusted_kr;
67 void importKey( const Pathname &keyfile, bool trusted = false);
68 PublicKey readPublicKey( const Pathname &keyfile );
69 std::string readSignatureKeyId( const Pathname &keyfile );
71 void deleteKey( const std::string &id, bool trusted );
72 std::list<PublicKey> trustedPublicKeys();
73 std::list<PublicKey> publicKeys();
75 bool verifyFileSignatureWorkflow( const Pathname &file, const Pathname &signature);
77 bool verifyFileSignature( const Pathname &file, const Pathname &signature);
78 bool verifyFileTrustedSignature( const Pathname &file, const Pathname &signature);
80 //mutable std::map<Locale, std::string> translations;
81 bool verifyFile( const Pathname &file, const Pathname &signature, const Pathname &keyring);
82 void importKey( const Pathname &keyfile, const Pathname &keyring);
83 void deleteKey( const std::string &id, const Pathname &keyring );
84 std::list<PublicKey> publicKeys(const Pathname &keyring);
86 bool publicKeyExists( std::string id, const Pathname &keyring);
91 /** Offer default Impl. */
92 static shared_ptr<Impl> nullimpl()
94 static shared_ptr<Impl> _nullimpl( new Impl );
99 friend Impl * rwcowClone<Impl>( const Impl * rhs );
100 /** clone for RWCOW_pointer */
102 { return new Impl( *this ); }
105 void KeyRing::Impl::importKey( const Pathname &keyfile, bool trusted)
107 importKey( keyfile, trusted ? _trusted_kr : _general_kr );
110 void KeyRing::Impl::deleteKey( const std::string &id, bool trusted)
112 deleteKey( id, trusted ? _trusted_kr : _general_kr );
115 std::list<PublicKey> KeyRing::Impl::publicKeys()
117 return publicKeys( _general_kr );
120 std::list<PublicKey> KeyRing::Impl::trustedPublicKeys()
122 return publicKeys( _trusted_kr );
125 bool KeyRing::Impl::verifyFileTrustedSignature( const Pathname &file, const Pathname &signature)
127 return verifyFile( file, signature, _trusted_kr );
130 bool KeyRing::Impl::verifyFileSignature( const Pathname &file, const Pathname &signature)
132 return verifyFile( file, signature, _general_kr );
135 bool KeyRing::Impl::publicKeyExists( std::string id, const Pathname &keyring)
137 std::list<PublicKey> keys = publicKeys(keyring);
138 for (std::list<PublicKey>::const_iterator it = keys.begin(); it != keys.end(); it++)
140 if ( id == (*it).id )
146 bool KeyRing::Impl::verifyFileSignatureWorkflow( const Pathname &file, const Pathname &signature)
153 PublicKey KeyRing::Impl::readPublicKey( const Pathname &keyfile )
158 "--with-fingerprint",
166 keyfile.asString().c_str(),
170 ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
175 boost::regex rxColons("^([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):\n$");
177 // pub:-:1024:17:A84EDAE89C800ACA:2000-10-19:2008-06-21::-:SuSE Package Signing Key <build@suse.de>:
180 for(line = prog.receiveLine(), count=0; !line.empty(); line = prog.receiveLine(), count++ )
182 //MIL << "[" << line << "]" << std::endl;
184 if(boost::regex_match(line, what, rxColons, boost::match_extra))
186 if ( what[1] == "pub" )
192 //dumpRegexpResults(what);
199 std::list<PublicKey> KeyRing::Impl::publicKeys(const Pathname &keyring)
205 "--list-public-keys",
207 "--with-fingerprint",
209 keyring.asString().c_str(),
212 std::list<PublicKey> keys;
214 ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
218 boost::regex rxColons("^([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):\n$");
219 for(line = prog.receiveLine(), count=0; !line.empty(); line = prog.receiveLine(), count++ )
221 //MIL << line << std::endl;
223 if(boost::regex_match(line, what, rxColons, boost::match_extra))
225 if ( what[1] == "pub" )
230 MIL << "Found key " << key.id << " [" << key.name << "]" << std::endl;
233 dumpRegexpResults(what);
240 void KeyRing::Impl::importKey( const Pathname &keyfile, const Pathname &keyring)
251 keyring.asString().c_str(),
253 keyfile.asString().c_str(),
258 ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
262 ZYPP_THROW(Exception("failed to import key"));
265 void KeyRing::Impl::deleteKey( const std::string &id, const Pathname &keyring )
277 keyring.asString().c_str(),
283 ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
285 int code = prog.close();
287 ZYPP_THROW(Exception("Failed to delete key."));
289 MIL << "Deleted key " << id << " from keyring " << keyring << std::endl;
293 std::string KeyRing::Impl::readSignatureKeyId( const Pathname &keyfile )
295 // HACK create a tmp keyring with no keys
308 dir.path().asString().c_str(),
309 keyfile.asString().c_str(),
313 ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
318 boost::regex rxNoKey("^\\[GNUPG:\\] NO_PUBKEY (.+)\n$");
320 for(line = prog.receiveLine(), count=0; !line.empty(); line = prog.receiveLine(), count++ )
322 //MIL << "[" << line << "]" << std::endl;
324 if(boost::regex_match(line, what, rxNoKey, boost::match_extra))
326 if ( what.size() > 1 )
328 //dumpRegexpResults(what);
335 bool KeyRing::Impl::verifyFile( const Pathname &file, const Pathname &signature, const Pathname &keyring)
347 keyring.asString().c_str(),
349 signature.asString().c_str(),
350 file.asString().c_str(),
354 // no need to parse output for now
355 // [GNUPG:] SIG_ID yCc4u223XRJnLnVAIllvYbUd8mQ 2006-03-29 1143618744
356 // [GNUPG:] GOODSIG A84EDAE89C800ACA SuSE Package Signing Key <build@suse.de>
357 // gpg: Good signature from "SuSE Package Signing Key <build@suse.de>"
358 // [GNUPG:] VALIDSIG 79C179B2E1C820C1890F9994A84EDAE89C800ACA 2006-03-29 1143618744 0 3 0 17 2 00 79C179B2E1C820C1890F9994A84EDAE89C800ACA
359 // [GNUPG:] TRUST_UNDEFINED
361 // [GNUPG:] ERRSIG A84EDAE89C800ACA 17 2 00 1143618744 9
362 // [GNUPG:] NO_PUBKEY A84EDAE89C800ACA
364 ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
366 return (prog.close() == 0) ? true : false;
369 ///////////////////////////////////////////////////////////////////
371 ///////////////////////////////////////////////////////////////////
373 // CLASS NAME : KeyRing
375 ///////////////////////////////////////////////////////////////////
377 ///////////////////////////////////////////////////////////////////
379 // METHOD NAME : KeyRing::KeyRing
380 // METHOD TYPE : Ctor
383 : _pimpl( Impl::nullimpl() )
386 ///////////////////////////////////////////////////////////////////
388 // METHOD NAME : KeyRing::KeyRing
389 // METHOD TYPE : Ctor
391 KeyRing::KeyRing( const Pathname &general_kr, const Pathname &trusted_kr )
392 : _pimpl( new Impl(general_kr, trusted_kr) )
395 ///////////////////////////////////////////////////////////////////
397 // METHOD NAME : KeyRing::~KeyRing
398 // METHOD TYPE : Dtor
403 ///////////////////////////////////////////////////////////////////
405 // Forward to implementation:
407 ///////////////////////////////////////////////////////////////////
409 void KeyRing::importKey( const Pathname &keyfile, bool trusted)
411 _pimpl->importKey(keyfile, trusted);
414 PublicKey KeyRing::readPublicKey( const Pathname &keyfile )
416 return _pimpl->readPublicKey(keyfile);
419 std::string KeyRing::readSignatureKeyId( const Pathname &keyfile )
421 return _pimpl->readSignatureKeyId(keyfile);
424 void KeyRing::deleteKey( const std::string &id, bool trusted )
426 _pimpl->deleteKey(id, trusted);
429 std::list<PublicKey> KeyRing::publicKeys()
431 return _pimpl->publicKeys();
434 std::list<PublicKey> KeyRing::trustedPublicKeys()
436 return _pimpl->trustedPublicKeys();
439 bool KeyRing::verifyFileSignatureWorkflow( const Pathname &file, const Pathname &signature)
441 return _pimpl->verifyFileSignatureWorkflow(file, signature);
444 bool KeyRing::verifyFileSignature( const Pathname &file, const Pathname &signature)
446 return _pimpl->verifyFileSignature(file, signature);
449 bool KeyRing::verifyFileTrustedSignature( const Pathname &file, const Pathname &signature)
451 return _pimpl->verifyFileTrustedSignature(file, signature);
454 /////////////////////////////////////////////////////////////////
456 ///////////////////////////////////////////////////////////////////