static bool printLine( const std::string &line )
{
MIL << line << std::endl;
+ return true;
}
static void dumpFile(const Pathname &file)
bool KeyRingReport::askUserToAcceptUnsignedFile( const std::string &file )
{ return _keyRingDefaultAccept; }
- bool KeyRingReport::askUserToAcceptUnknownKey( const std::string &file, const std::string &keyid, const std::string &keyname, const std::string &fingerprint )
+ bool KeyRingReport::askUserToAcceptUnknownKey( const std::string &file, const std::string &id )
{ return _keyRingDefaultAccept; }
- bool KeyRingReport::askUserToTrustKey( const std::string &keyid, const std::string &keyname, const std::string &fingerprint )
+ bool KeyRingReport::askUserToTrustKey( const PublicKey &key )
{ return _keyRingDefaultAccept; }
- bool KeyRingReport::askUserToAcceptVerificationFailed( const std::string &file, const std::string &keyid, const std::string &keyname, const std::string &fingerprint )
+ bool KeyRingReport::askUserToImportKey( const PublicKey &key)
{ return _keyRingDefaultAccept; }
-
+
+ bool KeyRingReport::askUserToAcceptVerificationFailed( const std::string &file, const PublicKey &key )
+ { return _keyRingDefaultAccept; }
+
///////////////////////////////////////////////////////////////////
//
// CLASS NAME : KeyRing::Impl
/** KeyRing implementation. */
struct KeyRing::Impl
{
- Impl()
+ Impl(const Pathname &baseTmpDir)
+ : _trusted_tmp_dir(baseTmpDir, "zypp-trusted-kr")
+ , _general_tmp_dir(baseTmpDir, "zypp-general-kr")
+ , _base_dir( baseTmpDir )
+
{
- _general_kr = _general_tmp_dir.path();
- _trusted_kr = _trusted_tmp_dir.path();
}
/*
filesystem::assert_dir(general_kr);
filesystem::assert_dir(trusted_kr);
- _general_kr = general_kr;
- _trusted_kr = trusted_kr;
+ generalKeyRing() = general_kr;
+ trustedKeyRing() = trusted_kr;
}
*/
- void importKey( const Pathname &keyfile, bool trusted = false);
- PublicKey readPublicKey( const Pathname &keyfile );
- std::string readSignatureKeyId( const Pathname &data, const Pathname &keyfile );
-
+ 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();
//mutable std::map<Locale, std::string> translations;
bool verifyFile( const Pathname &file, const Pathname &signature, const Pathname &keyring);
void importKey( const Pathname &keyfile, const Pathname &keyring);
-
- void exportKey( std::string id, const Pathname &keyfile, bool trusted);
-
+ PublicKey exportKey( std::string id, const Pathname &keyring);
+ void dumpPublicKey( const std::string &id, const Pathname &keyring, std::ostream &stream );
void deleteKey( const std::string &id, const Pathname &keyring );
std::list<PublicKey> publicKeys(const Pathname &keyring);
bool publicKeyExists( std::string id, const Pathname &keyring);
- Pathname _general_kr;
- Pathname _trusted_kr;
+ const Pathname generalKeyRing() const;
+ const Pathname trustedKeyRing() const;
// Used for trusted and untrusted keyrings
TmpDir _trusted_tmp_dir;
TmpDir _general_tmp_dir;
+ Pathname _base_dir;
public:
/** Offer default Impl. */
static shared_ptr<Impl> nullimpl()
{
- static shared_ptr<Impl> _nullimpl( new Impl );
+ static shared_ptr<Impl> _nullimpl( new Impl( Pathname("/var/tmp") ) );
return _nullimpl;
}
{ return new Impl( *this ); }
};
- void KeyRing::Impl::importKey( const Pathname &keyfile, bool trusted)
+
+ const Pathname KeyRing::Impl::generalKeyRing() const
{
- importKey( keyfile, trusted ? _trusted_kr : _general_kr );
+ return _general_tmp_dir.path();
+ }
+
+ const Pathname KeyRing::Impl::trustedKeyRing() const
+ {
+ return _trusted_tmp_dir.path();
+ }
+
+ void KeyRing::Impl::importKey( const PublicKey &key, bool trusted)
+ {
+ callback::SendReport<KeyRingSignals> emitSignal;
+
+ importKey( key.path(), trusted ? trustedKeyRing() : generalKeyRing() );
}
void KeyRing::Impl::deleteKey( const std::string &id, bool trusted)
{
- deleteKey( id, trusted ? _trusted_kr : _general_kr );
+ deleteKey( id, trusted ? trustedKeyRing() : generalKeyRing() );
}
std::list<PublicKey> KeyRing::Impl::publicKeys()
{
- return publicKeys( _general_kr );
+ return publicKeys( generalKeyRing() );
}
std::list<PublicKey> KeyRing::Impl::trustedPublicKeys()
{
- return publicKeys( _trusted_kr );
+ return publicKeys( trustedKeyRing() );
}
bool KeyRing::Impl::verifyFileTrustedSignature( const Pathname &file, const Pathname &signature)
{
- return verifyFile( file, signature, _trusted_kr );
+ return verifyFile( file, signature, trustedKeyRing() );
}
bool KeyRing::Impl::verifyFileSignature( const Pathname &file, const Pathname &signature)
{
- return verifyFile( file, signature, _general_kr );
+ return verifyFile( file, signature, generalKeyRing() );
}
+ bool KeyRing::Impl::isKeyTrusted( const std::string &id)
+ {
+ return publicKeyExists( id, trustedKeyRing() );
+ }
+
+ bool KeyRing::Impl::isKeyKnown( const std::string &id )
+ {
+ if ( publicKeyExists( id, trustedKeyRing() ) )
+ return true;
+ else
+ return publicKeyExists( id, generalKeyRing() );
+ }
+
bool KeyRing::Impl::publicKeyExists( std::string id, const Pathname &keyring)
{
+ MIL << "Searching key [" << id << "] in keyring " << keyring << std::endl;
std::list<PublicKey> keys = publicKeys(keyring);
for (std::list<PublicKey>::const_iterator it = keys.begin(); it != keys.end(); it++)
{
- if ( id == (*it).id )
+ if ( id == (*it).id() )
return true;
}
return false;
}
-
- void KeyRing::Impl::exportKey( std::string id, const Pathname &keyfile, bool trusted)
+
+ 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, trusted, os );
+ dumpPublicKey( id, keyring, os );
os.close();
+ PublicKey key(keyfile);
+ return key;
+ }
+ catch (BadKeyException &e)
+ {
+ ERR << "Cannot create public key " << id << " from " << keyring << " keyring to file " << e.keyFile() << std::endl;
+ ZYPP_THROW(Exception("Cannot create public key " + id + " from " + keyring.asString() + " keyring to file " + e.keyFile().asString() ) );
}
catch (std::exception &e)
{
- ERR << "Cannot export key " << id << " from " << (trusted ? "trusted" : "untrusted ") << " keyring to file " << keyfile << std::endl;
+ ERR << "Cannot export key " << id << " from " << keyring << " keyring to file " << keyfile << std::endl;
}
+ return PublicKey();
}
void KeyRing::Impl::dumpPublicKey( const std::string &id, bool trusted, std::ostream &stream )
{
- Pathname keyring = trusted ? _trusted_kr : _general_kr;
+ dumpPublicKey( id, ( trusted ? trustedKeyRing() : generalKeyRing() ), stream );
+ }
+
+ void KeyRing::Impl::dumpPublicKey( const std::string &id, const Pathname &keyring, std::ostream &stream )
+ {
const char* argv[] =
{
"gpg",
+ "--no-default-keyring",
"--quiet",
"--no-tty",
"--no-greeting",
// if signature does not exists, ask user if he wants to accept unsigned file.
if( signature.empty() || (!PathInfo(signature).isExist()) )
{
- bool res = report->askUserToAcceptUnsignedFile( filedesc );
- MIL << "User decision on unsigned file: " << res << endl;
- return res;
+ bool res = report->askUserToAcceptUnsignedFile( filedesc );
+ MIL << "User decision on unsigned file: " << res << endl;
+ return res;
}
// get the id of the signature
- std::string id = readSignatureKeyId(file, signature);
+ std::string id = readSignatureKeyId(signature);
// doeskey exists in trusted keyring
- if ( publicKeyExists( id, _trusted_kr ) )
+ if ( publicKeyExists( id, trustedKeyRing() ) )
{
- TmpFile trustedKey;
- exportKey( id, trustedKey.path(), true);
- PublicKey key = readPublicKey(trustedKey.path());
- MIL << "Key " << id << " " << key.name << " is trusted" << std::endl;
+ PublicKey key = exportKey( id, trustedKeyRing() );
+
+ MIL << "Key " << id << " " << key.name() << " is trusted" << std::endl;
// it exists, is trusted, does it validates?
- if ( verifyFile( file, signature, _trusted_kr ) )
+ if ( verifyFile( file, signature, trustedKeyRing() ) )
return true;
else
- return report->askUserToAcceptVerificationFailed( filedesc, key.id, key.name, key.fingerprint );
+ return report->askUserToAcceptVerificationFailed( filedesc, key );
}
else
{
- if ( publicKeyExists( id, _general_kr ) )
+ if ( publicKeyExists( id, generalKeyRing() ) )
{
- TmpFile unKey;
- exportKey( id, unKey.path(), false);
- MIL << "Exported key " << id << " to " << unKey << std::endl;
-
- PublicKey key = readPublicKey(unKey.path());
- MIL << "Key " << id << " " << key.name << " is not trusted" << std::endl;
+ PublicKey key = exportKey( id, generalKeyRing());
+ MIL << "Exported key " << id << " to " << key.path() << std::endl;
+ MIL << "Key " << id << " " << key.name() << " is not trusted" << std::endl;
// ok the key is not trusted, ask the user to trust it or not
-#warning We need the key details passed to the callback
- if ( report->askUserToTrustKey(key.id, key.name, key.fingerprint) )
+ #warning We need the key details passed to the callback
+ if ( report->askUserToTrustKey( key ) )
{
- MIL << "User wants to trust key " << id << " " << key.name << std::endl;
+ MIL << "User wants to trust key " << id << " " << key.name() << std::endl;
//dumpFile(unKey.path());
- importKey( unKey.path(), _trusted_kr );
- emitSignal->trustedKeyAdded( (const KeyRing &)(*this), id, key.name, key.fingerprint );
+ Pathname which_keyring;
+ if ( report->askUserToImportKey( key ) )
+ {
+ MIL << "User wants to import key " << id << " " << key.name() << std::endl;
+ importKey( key.path(), trustedKeyRing() );
+ emitSignal->trustedKeyAdded( (const KeyRing &)(*this), key );
+ which_keyring = trustedKeyRing();
+ }
+ else
+ {
+ which_keyring = generalKeyRing();
+ }
// emit key added
- if ( verifyFile( file, signature, _trusted_kr ) )
+ if ( verifyFile( file, signature, which_keyring ) )
{
MIL << "File signature is verified" << std::endl;
return true;
else
{
MIL << "File signature check fails" << std::endl;
- if ( report->askUserToAcceptVerificationFailed( filedesc, key.id, key.name, key.fingerprint ) )
+ if ( report->askUserToAcceptVerificationFailed( filedesc, key ) )
{
MIL << "User continues anyway." << std::endl;
return true;
}
else
{
- MIL << "User does not want to trust key " << id << " " << key.name << std::endl;
+ MIL << "User does not want to trust key " << id << " " << key.name() << std::endl;
return false;
}
}
else
{
// unknown key...
- if ( report->askUserToAcceptUnknownKey( filedesc, id, "", "" ) )
+ MIL << "File [" << file << "] ( " << filedesc << " ) signed with unknown key [" << id << "]" << std::endl;
+ if ( report->askUserToAcceptUnknownKey( filedesc, id ) )
{
MIL << "User wants to accept unknown key " << id << std::endl;
return true;
return false;
}
-
- PublicKey KeyRing::Impl::readPublicKey( const Pathname &keyfile )
- {
- const char* argv[] =
- {
- "gpg",
- "--with-fingerprint",
- "--with-colons",
- "--quiet",
- "--no-tty",
- "--no-greeting",
- "--batch",
- "--status-fd",
- "1",
- keyfile.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 <build@suse.de>:
-
- PublicKey key;
- for(line = prog.receiveLine(), count=0; !line.empty(); line = prog.receiveLine(), count++ )
- {
- //MIL << "[" << line << "]" << std::endl;
- str::smatch what;
- if(str::regex_match(line, what, rxColons, str::match_extra))
- {
- if ( what[1] == "pub" )
- {
- key.id = what[5];
- key.name = what[10];
- //return key;
- }
- else if ( what[1] == "fpr" )
- {
- key.fingerprint = what[10];
- }
- //dumpRegexpResults(what);
- }
- }
- prog.close();
- return key;
- }
-
std::list<PublicKey> KeyRing::Impl::publicKeys(const Pathname &keyring)
{
const char* argv[] =
{
"gpg",
+ "--no-default-keyring",
"--quiet",
"--list-public-keys",
"--with-colons",
str::smatch what;
if(str::regex_match(line, what, rxColons, str::match_extra))
{
- PublicKey key;
+ string id;
if ( what[1] == "pub" )
{
- key.id = what[5];
- key.name = what[10];
-
+ id = what[5];
+
std::string line2;
for(line2 = prog.receiveLine(); !line2.empty(); line2 = prog.receiveLine(), count++ )
{
{
if ( (what2[1] == "fpr") && (what2[1] != "pub") && (what2[1] !="sub"))
{
- key.fingerprint = what2[10];
+ //key.fingerprint = what2[10];
break;
}
}
}
+ PublicKey key(exportKey( id, keyring ));
keys.push_back(key);
- MIL << "Found key " << "[" << key.id << "]" << " [" << key.name << "]" << " [" << key.fingerprint << "]" << std::endl;
+ MIL << "Found key " << "[" << key.id() << "]" << " [" << key.name() << "]" << " [" << key.fingerprint() << "]" << std::endl;
}
//dumpRegexpResults(what);
}
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",
+ "--no-default-keyring",
"--quiet",
"--no-tty",
"--no-greeting",
const char* argv[] =
{
"gpg",
+ "--no-default-keyring",
"--yes",
"--quiet",
"--no-tty",
}
- std::string KeyRing::Impl::readSignatureKeyId( const Pathname &data, const Pathname &keyfile )
+ std::string KeyRing::Impl::readSignatureKeyId(const Pathname &signature )
{
+ MIL << "Deetermining key id if signature " << signature << std::endl;
// HACK create a tmp keyring with no keys
- TmpDir dir;
+ TmpDir dir(_base_dir, "fake-keyring");
+ TmpFile fakeData(_base_dir, "fake-data");
const char* argv[] =
{
"gpg",
+ "--no-default-keyring",
"--quiet",
"--no-tty",
"--no-greeting",
"--homedir",
dir.path().asString().c_str(),
"--verify",
- keyfile.asString().c_str(),
- data.asString().c_str(),
+ signature.asString().c_str(),
+ fakeData.path().asString().c_str(),
NULL
};
//dumpRegexpResults(what);
}
}
+ MIL << "Determined key id [" << id << "] for signature " << signature << std::endl;
prog.close();
return id;
}
const char* argv[] =
{
"gpg",
+ "--no-default-keyring",
"--quiet",
"--no-tty",
"--batch",
// METHOD NAME : KeyRing::KeyRing
// METHOD TYPE : Ctor
//
- KeyRing::KeyRing()
- : _pimpl( new Impl() )
+ KeyRing::KeyRing(const Pathname &baseTmpDir)
+ : _pimpl( new Impl(baseTmpDir) )
{}
///////////////////////////////////////////////////////////////////
//
///////////////////////////////////////////////////////////////////
- void KeyRing::importKey( const Pathname &keyfile, bool trusted)
- {
- _pimpl->importKey(keyfile, trusted);
- }
-
- PublicKey KeyRing::readPublicKey( const Pathname &keyfile )
+
+ void KeyRing::importKey( const PublicKey &key, bool trusted )
{
- return _pimpl->readPublicKey(keyfile);
+ _pimpl->importKey( key.path(), trusted );
}
-
- std::string KeyRing::readSignatureKeyId( const Pathname &data, const Pathname &keyfile )
+
+ std::string KeyRing::readSignatureKeyId( const Pathname &signature )
{
- return _pimpl->readSignatureKeyId(data, keyfile);
+ return _pimpl->readSignatureKeyId(signature);
}
void KeyRing::deleteKey( const std::string &id, bool trusted )
_pimpl->dumpPublicKey( id, trusted, stream);
}
+ bool KeyRing::isKeyTrusted( const std::string &id )
+ {
+ return _pimpl->isKeyTrusted(id);
+ }
+
+ bool KeyRing::isKeyKnown( const std::string &id )
+ {
+ return _pimpl->isKeyTrusted(id);
+ }
+
/////////////////////////////////////////////////////////////////
} // namespace zypp
///////////////////////////////////////////////////////////////////