#include "Printing.h"
#include "Tools.h"
+#include <zypp/Digest.h>
+#include <zypp/KeyRing.h>
+
#include <zypp/base/Logger.h>
#include <zypp/base/LogControl.h>
#include <zypp/base/String.h>
{}
};
-inline Source_Ref XcreateSource( const Url & url_r )
+
+inline bool keyDef( bool def )
+{ return def; }
+
+struct DigestReceive : public zypp::callback::ReceiveReport<zypp::DigestReport>
{
- Source_Ref ret;
- string a( "createSource: 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345" );
- //Measure x( a );
- //Measure x( "createSource: " );//+ url_r.asString() );
- try
- {
- ret = SourceFactory().createFrom( url_r, "/", Date::now().asSeconds() );
- }
- catch ( const Exception & )
- {
- return Source_Ref::noSource;
- }
- //x.start( "parseSource: " + url_r.asString() );
+ virtual bool askUserToAcceptNoDigest( const zypp::Pathname & file )
{
- //zypp::base::LogControl::TmpLineWriter shutUp;
- ret.resolvables();
+ bool def = zypp::DigestReport::askUserToAcceptNoDigest( file );
+ SEC << "AcceptNoDigest " << file << " (" << def << ')' << endl;
+ return keyDef( def );
+ }
+};
+struct KeyRingReceive : public zypp::callback::ReceiveReport<zypp::KeyRingReport>
+{
+ virtual bool askUserToTrustKey( const std::string & keyid,
+ const std::string & keyname,
+ const std::string & keydetails )
+ {
+ bool def = zypp::KeyRingReport::askUserToTrustKey( keyid, keyname, keydetails );
+ SEC << "TrustKey " << keyid << ' ' << keyname << ' ' << keydetails << " (" << def << ')' << endl;
+ return keyDef( def );
}
- //x.stop();
- MIL << "Content " << ret << "{" << endl;
- rstats( ret.resolvables() );
- MIL << "}" << endl;
- return ret;
-}
+ virtual bool askUserToAcceptUnknownKey( const zypp::Pathname & path,
+ const std::string & keyid,
+ const std::string & keyname )
+ {
+ bool def = zypp::KeyRingReport::askUserToAcceptUnknownKey( path, keyid, keyname );
+ SEC << "AcceptUnknownKey " << path << ' ' << keyid << ' ' << keyname << " (" << def << ')' << endl;
+ return keyDef( def );
+ }
+
+ virtual bool askUserToAcceptUnsignedFile( const zypp::Pathname & file )
+ {
+ bool def = zypp::KeyRingReport::askUserToAcceptUnsignedFile( file );
+ SEC << "AcceptUnsignedFile " << file << " (" << def << ')' << endl;
+ return keyDef( def );
+ }
+
+ virtual bool askUserToAcceptVerificationFailed( const zypp::Pathname & file,
+ const std::string & keyid,
+ const std::string & keyname )
+ {
+ bool def = zypp::KeyRingReport::askUserToAcceptVerificationFailed( file, keyid, keyname );
+ SEC << "AcceptVerificationFailed " << file << ' ' << keyid << ' ' << keyname << " (" << def << ')' << endl;
+ return keyDef( def );
+ }
+};
+
+struct KeyRingCallbacks
+{
+ KeyRingCallbacks()
+ {
+ _digestReceive.connect();
+ _keyRingReceive.connect();
+ }
+ ~KeyRingCallbacks()
+ {
+ _digestReceive.disconnect();
+ _keyRingReceive.disconnect();
+ }
+
+ DigestReceive _digestReceive;
+ KeyRingReceive _keyRingReceive;
+
+};
+static KeyRingCallbacks cbs;
void checkSource( const Url & url )
{
- Source_Ref src( XcreateSource( url ) );
+ Source_Ref src( createSource( url ) );
}
void checkSource( const std::string & urlstr )
{ checkSource( Url(urlstr) ); }
-------------------------------------------------------------------
+Wed Apr 19 13:48:26 CEST 2006 - ma@suse.de
+
+- Introduced $ZYPP_KEYRING_DEFAULT_ACCEPT_ALL. If this environment
+ variable is present, all signature checking callbacks will default
+ to 'accept', in case no recipient is present.
+
+-------------------------------------------------------------------
Wed Apr 19 11:37:47 CEST 2006 - dmacvicar@suse.de
-- read content file on construction, and make
- provideProduct only insert the already
+- read content file on construction, and make
+ provideProduct only insert the already
read product object into the store (#165826)
(dmacvicar)
- When the signature is not found, warn the
- user about a unsigned source. When the
- key is not found, do nothing, it can be in the
+ user about a unsigned source. When the
+ key is not found, do nothing, it can be in the
keyring already. (#166016) (dmacvicar)
-- enable key verification only if
- ZYPP_CHECKSIG env var is set (dmacvicar)
+- enable key verification only if
+ ZYPP_CHECKSIG env var is set (dmacvicar)
- r1529
-------------------------------------------------------------------
- fix bugfix 164365, fix bug 167285
Actually clear the transcation state instead of locking it
- to 'dont transact'
+ to 'dont transact'
- rev 3122
-------------------------------------------------------------------
Fri Apr 14 16:04:35 CEST 2006 - visnov@suse.cz
- new callbacks for failing digest
-- rev 3098
+- rev 3098
-------------------------------------------------------------------
Thu Apr 13 16:59:38 CEST 2006 - kkaempf@suse.de
-------------------------------------------------------------------
Thu Apr 13 17:01:41 CEST 2006 - visnov@suse.cz
-- ask for file without a checksum (#165125)
+- ask for file without a checksum (#165125)
-------------------------------------------------------------------
Thu Apr 13 16:00:21 CEST 2006 - kkaempf@suse.de
Thu Apr 13 15:19:20 CEST 2006 - visnov@suse.cz
- Ask user if signature file does not exist (#163765)
-- handle repomd.xml.asc as optional file (#163765)
+- handle repomd.xml.asc as optional file (#163765)
- rev 3089
-------------------------------------------------------------------
{ /////////////////////////////////////////////////////////////////
IMPL_PTR_TYPE(KeyRing);
-
+
static void dumpRegexpResults( const boost::smatch &what )
{
for ( unsigned int k=0; k < what.size(); k++)
XXX << "[match "<< k << "] [" << what[k] << "]" << std::endl;
}
}
-
+
static bool printLine( const std::string &line )
{
MIL << line << std::endl;
}
-
+
static void dumpFile(const Pathname &file)
{
std::ifstream is(file.asString().c_str());
- iostr::forEachLine( is, printLine);
+ iostr::forEachLine( is, printLine);
+ }
+
+ namespace
+ {
+ bool _keyRingDefaultAccept( getenv("ZYPP_KEYRING_DEFAULT_ACCEPT_ALL") );
}
bool KeyRingReport::askUserToAcceptUnsignedFile( const Pathname &file )
- { return true; }
+ { return _keyRingDefaultAccept; }
bool KeyRingReport::askUserToAcceptUnknownKey( const Pathname &file, const std::string &keyid, const std::string &keyname )
- { return true; }
+ { return _keyRingDefaultAccept; }
bool KeyRingReport::askUserToTrustKey( const std::string &keyid, const std::string &keyname, const std::string &keydetails )
- { return true; }
+ { return _keyRingDefaultAccept; }
bool KeyRingReport::askUserToAcceptVerificationFailed( const Pathname &file, const std::string &keyid, const std::string &keyname )
- { return true; }
-
+ { return _keyRingDefaultAccept; }
+
///////////////////////////////////////////////////////////////////
//
// CLASS NAME : KeyRing::Impl
{
filesystem::assert_dir(general_kr);
filesystem::assert_dir(trusted_kr);
-
+
_general_kr = general_kr;
_trusted_kr = 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 deleteKey( const std::string &id, bool trusted );
std::list<PublicKey> trustedPublicKeys();
std::list<PublicKey> publicKeys();
-
+
void dumpPublicKey( const std::string &id, bool trusted, std::ostream &stream );
-
+
bool verifyFileSignatureWorkflow( const Pathname &file, const Pathname &signature);
-
+
bool verifyFileSignature( const Pathname &file, const Pathname &signature);
bool verifyFileTrustedSignature( const Pathname &file, const Pathname &signature);
private:
//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);
-
+
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;
-
+
// Used for trusted and untrusted keyrings
TmpDir _trusted_tmp_dir;
TmpDir _general_tmp_dir;
Impl * clone() const
{ return new Impl( *this ); }
};
-
+
void KeyRing::Impl::importKey( const Pathname &keyfile, bool trusted)
{
importKey( keyfile, trusted ? _trusted_kr : _general_kr );
}
-
+
void KeyRing::Impl::deleteKey( const std::string &id, bool trusted)
{
deleteKey( id, trusted ? _trusted_kr : _general_kr );
}
-
+
std::list<PublicKey> KeyRing::Impl::publicKeys()
{
return publicKeys( _general_kr );
}
-
+
std::list<PublicKey> KeyRing::Impl::trustedPublicKeys()
{
return publicKeys( _trusted_kr );
}
-
+
bool KeyRing::Impl::verifyFileTrustedSignature( const Pathname &file, const Pathname &signature)
{
return verifyFile( file, signature, _trusted_kr );
}
-
+
bool KeyRing::Impl::verifyFileSignature( const Pathname &file, const Pathname &signature)
{
return verifyFile( file, signature, _general_kr );
}
-
+
bool KeyRing::Impl::publicKeyExists( std::string id, const Pathname &keyring)
{
std::list<PublicKey> keys = publicKeys(keyring);
}
return false;
}
-
+
void KeyRing::Impl::exportKey( std::string id, const Pathname &keyfile, bool trusted)
- {
- try {
+ {
+ try {
std::ofstream os(keyfile.asString().c_str());
dumpPublicKey( id, trusted, os );
os.close();
ERR << "Cannot export key " << id << " from " << (trusted ? "trusted" : "untrusted ") << " keyring to file " << keyfile << std::endl;
}
}
-
+
void KeyRing::Impl::dumpPublicKey( const std::string &id, bool trusted, std::ostream &stream )
{
Pathname keyring = trusted ? _trusted_kr : _general_kr;
}
prog.close();
}
-
-
+
+
bool KeyRing::Impl::verifyFileSignatureWorkflow( const Pathname &file, const Pathname &signature)
{
if ( ! getenv("ZYPP_CHECKSIG") )
{
- MIL << "Digital signature check disabled. Accepting source." << std::endl;
+ MIL << "Digital signature check disabled. Accepting source." << std::endl;
return true;
}
-
+
callback::SendReport<KeyRingReport> report;
callback::SendReport<KeyRingSignals> emitSignal;
- MIL << "Going to verify signature for " << file << " with " << signature << std::endl;
-
+ MIL << "Going to verify signature for " << file << " with " << signature << std::endl;
+
// if signature does not exists, ask user if he wants to accept unsigned file.
if( signature.empty() || (!PathInfo(signature).isExist()) )
{
// get the id of the signature
std::string id = readSignatureKeyId(file, signature);
-
+
// doeskey exists in trusted keyring
if ( publicKeyExists( id, _trusted_kr ) )
{
MIL << "Key " << id << " " << key.name << " is trusted" << std::endl;
// it exists, is trusted, does it validates?
if ( verifyFile( file, signature, _trusted_kr ) )
- return true;
+ return true;
else
return report->askUserToAcceptVerificationFailed( file, key.id, key.name );
}
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;
// ok the key is not trusted, ask the user to trust it or not
{
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 );
-
+
// emit key added
if ( verifyFile( file, signature, _trusted_kr ) )
{
MIL << "File signature is verified" << std::endl;
- return true;
+ return true;
}
else
{
}
return false;
}
-
-
+
+
PublicKey KeyRing::Impl::readPublicKey( const Pathname &keyfile )
- {
+ {
const char* argv[] =
{
"gpg",
"--no-greeting",
"--batch",
"--status-fd",
- "1",
+ "1",
keyfile.asString().c_str(),
NULL
};
-
+
ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
-
+
std::string line;
int count = 0;
-
+
boost::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++ )
{
prog.close();
return key;
}
-
+
std::list<PublicKey> KeyRing::Impl::publicKeys(const Pathname &keyring)
{
const char* argv[] =
NULL
};
std::list<PublicKey> keys;
-
+
ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
std::string line;
int count = 0;
-
+
boost::regex rxColons("^([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):([^:]*):\n$");
for(line = prog.receiveLine(), count=0; !line.empty(); line = prog.receiveLine(), count++ )
{
prog.close();
return keys;
}
-
+
void KeyRing::Impl::importKey( const Pathname &keyfile, const Pathname &keyring)
{
const char* argv[] =
"--no-greeting",
"--no-permission-warning",
"--status-fd",
- "1",
+ "1",
"--homedir",
keyring.asString().c_str(),
"--import",
keyfile.asString().c_str(),
NULL
};
-
+
int code;
ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
code = prog.close();
-
+
//if ( code != 0 )
// ZYPP_THROW(Exception("failed to import key"));
}
-
+
void KeyRing::Impl::deleteKey( const std::string &id, const Pathname &keyring )
{
const char* argv[] =
id.c_str(),
NULL
};
-
+
ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
-
+
int code = prog.close();
if ( code )
ZYPP_THROW(Exception("Failed to delete key."));
- else
+ else
MIL << "Deleted key " << id << " from keyring " << keyring << std::endl;
- }
-
-
+ }
+
+
std::string KeyRing::Impl::readSignatureKeyId( const Pathname &data, const Pathname &keyfile )
- {
+ {
// HACK create a tmp keyring with no keys
TmpDir dir;
-
+
const char* argv[] =
{
"gpg",
data.asString().c_str(),
NULL
};
-
+
ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
-
+
std::string line;
int count = 0;
-
+
boost::regex rxNoKey("^\\[GNUPG:\\] NO_PUBKEY (.+)\n$");
std::string id;
for(line = prog.receiveLine(), count=0; !line.empty(); line = prog.receiveLine(), count++ )
}
prog.close();
return id;
- }
-
+ }
+
bool KeyRing::Impl::verifyFile( const Pathname &file, const Pathname &signature, const Pathname &keyring)
{
const char* argv[] =
file.asString().c_str(),
NULL
};
-
+
// no need to parse output for now
// [GNUPG:] SIG_ID yCc4u223XRJnLnVAIllvYbUd8mQ 2006-03-29 1143618744
// [GNUPG:] GOODSIG A84EDAE89C800ACA SuSE Package Signing Key <build@suse.de>
// gpg: Good signature from "SuSE Package Signing Key <build@suse.de>"
// [GNUPG:] VALIDSIG 79C179B2E1C820C1890F9994A84EDAE89C800ACA 2006-03-29 1143618744 0 3 0 17 2 00 79C179B2E1C820C1890F9994A84EDAE89C800ACA
// [GNUPG:] TRUST_UNDEFINED
-
+
// [GNUPG:] ERRSIG A84EDAE89C800ACA 17 2 00 1143618744 9
// [GNUPG:] NO_PUBKEY A84EDAE89C800ACA
ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
-
+
return (prog.close() == 0) ? true : false;
}
-
+
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
{
_pimpl->importKey(keyfile, trusted);
}
-
+
PublicKey KeyRing::readPublicKey( const Pathname &keyfile )
{
return _pimpl->readPublicKey(keyfile);
}
-
+
std::string KeyRing::readSignatureKeyId( const Pathname &data, const Pathname &keyfile )
{
return _pimpl->readSignatureKeyId(data, keyfile);
}
-
+
void KeyRing::deleteKey( const std::string &id, bool trusted )
{
_pimpl->deleteKey(id, trusted);
}
-
+
std::list<PublicKey> KeyRing::publicKeys()
{
return _pimpl->publicKeys();
}
-
+
std::list<PublicKey> KeyRing::trustedPublicKeys()
{
return _pimpl->trustedPublicKeys();
}
-
+
bool KeyRing::verifyFileSignatureWorkflow( const Pathname &file, const Pathname &signature)
{
return _pimpl->verifyFileSignatureWorkflow(file, signature);
}
-
+
bool KeyRing::verifyFileSignature( const Pathname &file, const Pathname &signature)
{
return _pimpl->verifyFileSignature(file, signature);
}
-
+
bool KeyRing::verifyFileTrustedSignature( const Pathname &file, const Pathname &signature)
{
return _pimpl->verifyFileTrustedSignature(file, signature);
}
-
+
void KeyRing::dumpPublicKey( const std::string &id, bool trusted, std::ostream &stream )
{
_pimpl->dumpPublicKey( id, trusted, stream);
}
-
+
/////////////////////////////////////////////////////////////////
} // namespace zypp
///////////////////////////////////////////////////////////////////