18 #include <boost/format.hpp>
37 #undef ZYPP_BASE_LOGGER_LOGGROUP
38 #define ZYPP_BASE_LOGGER_LOGGROUP "zypp::KeyRing"
40 #define GPG_BINARY "/usr/bin/gpg2"
54 {
return _keyRingDefaultAccept; }
58 MIL <<
"Set new KeyRing::DefaultAccept: " << value_r << endl;
59 _keyRingDefaultAccept = value_r;
90 struct CachedPublicKeyData
92 const std::list<PublicKeyData> & operator()(
const Pathname & keyring_r )
const
93 {
return getData( keyring_r ); }
104 Cache(
const Cache & rhs ) {}
107 typedef std::map<Pathname,Cache> CacheMap;
109 const std::list<PublicKeyData> & getData(
const Pathname & keyring_r )
const
112 if ( ! cache._keyringP )
115 cache._keyringP.reset(
new WatchFile( keyring_r/
"pubring.gpg",
WatchFile::NO_INIT ) );
117 return getData( keyring_r, cache );
120 const std::list<PublicKeyData> & getData(
const Pathname & keyring_r, Cache & cache_r )
const
122 if ( cache_r._keyringP->hasChanged() )
127 "--list-public-keys",
128 "--homedir", keyring_r.c_str(),
129 "--no-default-keyring",
133 "--with-fingerprint",
142 PublicKeyScanner scanner;
144 for( std::string line = prog.receiveLine(); !line.empty(); line = prog.receiveLine() )
146 scanner.scan( line );
150 cache_r._data.swap( scanner._keys );
151 MIL <<
"Found keys: " << cache_r._data << endl;
153 return cache_r._data;
168 Impl(
const Pathname & baseTmpDir )
173 MIL <<
"Current KeyRing::DefaultAccept: " << _keyRingDefaultAccept << endl;
177 void multiKeyImport(
const Pathname & keyfile_r,
bool trusted_r =
false );
178 void deleteKey(
const std::string &
id,
bool trusted );
197 void dumpPublicKey(
const std::string &
id,
bool trusted, std::ostream & stream )
206 const Pathname & file,
207 const std::string & filedesc,
208 const Pathname & signature,
217 bool verifyFile(
const Pathname & file,
const Pathname & signature,
const Pathname & keyring );
218 void importKey(
const Pathname & keyfile,
const Pathname & keyring );
223 void dumpPublicKey(
const std::string &
id,
const Pathname & keyring, std::ostream & stream );
226 void deleteKey(
const std::string &
id,
const Pathname & keyring );
228 std::list<PublicKey>
publicKeys(
const Pathname & keyring);
262 friend Impl * rwcowClone<Impl>(
const Impl * rhs );
265 {
return new Impl( *
this ); }
279 rpmdbEmitSignal->trustedKeyAdded( key );
280 emitSignal->trustedKeyAdded( key );
286 importKey( keyfile_r, trusted_r ? trustedKeyRing() : generalKeyRing() );
295 key = exportKey(
id, trustedKeyRing() );
298 deleteKey(
id, trusted ? trustedKeyRing() : generalKeyRing() );
305 rpmdbEmitSignal->trustedKeyRemoved( key );
306 emitSignal->trustedKeyRemoved( key );
312 MIL <<
"Searching key [" <<
id <<
"] in keyring " << keyring << endl;
313 const std::list<PublicKeyData> & keys(
publicKeyData( keyring ) );
314 for_( it, keys.begin(), keys.end() )
316 if (
id == (*it).id() )
326 return PublicKey( dumpPublicKeyToTmp( keyData.
id(), keyring ), keyData );
333 return PublicKey( dumpPublicKeyToTmp( keyData.
id(), keyring ), keyData );
336 WAR <<
"No key " <<
id <<
" to export from " << keyring << endl;
348 "--homedir", keyring.asString().c_str(),
349 "--no-default-keyring",
353 "--no-permission-warning",
369 MIL <<
"Going to export key " <<
id <<
" from " << keyring <<
" to " << tmpFile.
path() << endl;
371 std::ofstream os( tmpFile.
path().
c_str() );
378 const Pathname & file,
379 const std::string & filedesc,
380 const Pathname & signature,
384 MIL <<
"Going to verify signature for " << filedesc <<
" ( " << file <<
" ) with " << signature << endl;
387 if( signature.empty() || (!PathInfo( signature ).isExist()) )
389 bool res = report->askUserToAcceptUnsignedFile( filedesc, context );
390 MIL <<
"User decision on unsigned file: " << res << endl;
398 PublicKeyData trustedKeyData( publicKeyExists(
id, trustedKeyRing() ) );
399 if ( trustedKeyData )
401 MIL <<
"Key is trusted: " << trustedKeyData << endl;
405 PublicKeyData generalKeyData( publicKeyExists(
id, generalKeyRing() ) );
406 if ( generalKeyData )
413 MIL <<
"Key was updated. Saving new version into trusted keyring: " << generalKeyData << endl;
414 importKey( exportKey( generalKeyData, generalKeyRing() ),
true );
420 if ( verifyFile( file, signature, trustedKeyRing() ) )
424 if ( ! trustedKeyData )
425 trustedKeyData = publicKeyExists(
id, trustedKeyRing() );
426 return report->askUserToAcceptVerificationFailed( filedesc, exportKey( trustedKeyData, trustedKeyRing() ), context );
431 PublicKeyData generalKeyData( publicKeyExists(
id, generalKeyRing() ) );
432 if ( generalKeyData )
434 PublicKey key( exportKey( generalKeyData, generalKeyRing() ) );
435 MIL <<
"Exported key " <<
id <<
" to " << key.
path() << endl;
436 MIL <<
"Key " <<
id <<
" " << key.
name() <<
" is not trusted" << endl;
443 MIL <<
"User wants to trust key " <<
id <<
" " << key.
name() << endl;
446 Pathname whichKeyring;
449 MIL <<
"User wants to import key " <<
id <<
" " << key.
name() << endl;
451 whichKeyring = trustedKeyRing();
454 whichKeyring = generalKeyRing();
457 if ( verifyFile( file, signature, whichKeyring ) )
459 MIL <<
"File signature is verified" << endl;
464 MIL <<
"File signature check fails" << endl;
465 if ( report->askUserToAcceptVerificationFailed( filedesc, key, context ) )
467 MIL <<
"User continues anyway." << endl;
472 MIL <<
"User does not want to continue" << endl;
479 MIL <<
"User does not want to trust key " <<
id <<
" " << key.
name() << endl;
486 MIL <<
"File [" << file <<
"] ( " << filedesc <<
" ) signed with unknown key [" <<
id <<
"]" << endl;
487 if ( report->askUserToAcceptUnknownKey( filedesc,
id, context ) )
489 MIL <<
"User wants to accept unknown key " <<
id << endl;
494 MIL <<
"User does not want to accept unknown key " <<
id << endl;
504 const std::list<PublicKeyData> & keys(
publicKeyData( keyring ) );
505 std::list<PublicKey> ret;
507 for_( it, keys.begin(), keys.end() )
509 PublicKey key( exportKey( *it, keyring ) );
510 ret.push_back( key );
511 MIL <<
"Found key " << key << endl;
518 if ( ! PathInfo( keyfile ).isExist() )
521 _(
"Tried to import not existent key %s into keyring %s"))
522 % keyfile.asString() % keyring.asString())));
528 "--homedir", keyring.asString().c_str(),
529 "--no-default-keyring",
533 "--no-permission-warning",
535 keyfile.asString().c_str(),
549 "--homedir", keyring.asString().c_str(),
550 "--no-default-keyring",
562 int code = prog.
close();
566 MIL <<
"Deleted key " <<
id <<
" from keyring " << keyring << endl;
572 if ( ! PathInfo( signature ).isFile() )
574 _(
"Signature file %s not found"))% signature.asString())));
576 MIL <<
"Determining key id if signature " << signature << endl;
584 "--no-default-keyring",
590 signature.asString().c_str(),
599 str::regex rxNoKey(
"^\\[GNUPG:\\] NO_PUBKEY (.+)\n$" );
607 if ( what.
size() >= 1 )
618 MIL <<
"no output" << endl;
621 MIL <<
"Determined key id [" <<
id <<
"] for signature " << signature << endl;
632 "--homedir", keyring.asString().c_str(),
633 "--no-default-keyring",
639 signature.asString().c_str(),
640 file.asString().c_str(),
656 return ( prog.
close() == 0 ) ?
true :
false;
702 std::list<std::string> ret;
703 for_( it, keys.begin(), keys.end() )
705 ret.push_back( (*it).id() );
713 std::list<std::string> ret;
714 for_( it, keys.begin(), keys.end() )
716 ret.push_back( (*it).id() );
722 const Pathname & file,
723 const std::string filedesc,
724 const Pathname & signature,