_inRpmKeys = &rpmKey_r;
_inZyppKeys = nullptr;
if ( !keyRelease.empty() )
- DBG << "Old key in R: gpg-pubkey-" << rpmKey_r.version() << "-" << keyRelease << endl;
+ DBG << "Old key in Z: gpg-pubkey-" << rpmKey_r.version() << "-" << keyRelease << endl;
}
else if ( comp == 0 )
{
_inRpmKeys = nullptr;
_inZyppKeys = &zyppKey_r;
if ( !keyRelease.empty() )
- DBG << "Old key in Z: gpg-pubkey-" << zyppKey_r.gpgPubkeyVersion() << "-" << keyRelease << endl;
+ DBG << "Old key in R: gpg-pubkey-" << zyppKey_r.gpgPubkeyVersion() << "-" << keyRelease << endl;
}
else if ( comp == 0 )
{
{ static Rpmlog _rpmlog; return _rpmlog; }
};
-
-} // namespace
-///////////////////////////////////////////////////////////////////
-//
-// METHOD NAME : RpmDb::checkPackage
-// METHOD TYPE : RpmDb::CheckPackageResult
-//
-RpmDb::CheckPackageResult RpmDb::checkPackage( const Pathname & path_r, CheckPackageDetail & detail_r )
-{
- PathInfo file( path_r );
- if ( ! file.isFile() )
- {
- ERR << "Not a file: " << file << endl;
- return CHK_ERROR;
- }
-
- FD_t fd = ::Fopen( file.asString().c_str(), "r.ufdio" );
- if ( fd == 0 || ::Ferror(fd) )
+ RpmDb::CheckPackageResult doCheckPackageSig( const Pathname & path_r, // rpm file to check
+ const Pathname & root_r, // target root
+ bool requireGPGSig_r, // whether no gpg signature is to be reported
+ RpmDb::CheckPackageDetail & detail_r ) // detailed result
{
- ERR << "Can't open file for reading: " << file << " (" << ::Fstrerror(fd) << ")" << endl;
- if ( fd )
- ::Fclose( fd );
- return CHK_ERROR;
- }
- rpmts ts = ::rpmtsCreate();
- ::rpmtsSetRootDir( ts, root().asString().c_str() );
- ::rpmtsSetVSFlags( ts, RPMVSF_DEFAULT );
+ PathInfo file( path_r );
+ if ( ! file.isFile() )
+ {
+ ERR << "Not a file: " << file << endl;
+ return RpmDb::CHK_ERROR;
+ }
- rpmQVKArguments_s qva;
- memset( &qva, 0, sizeof(rpmQVKArguments_s) );
- qva.qva_flags = (VERIFY_DIGEST|VERIFY_SIGNATURE);
+ FD_t fd = ::Fopen( file.asString().c_str(), "r.ufdio" );
+ if ( fd == 0 || ::Ferror(fd) )
+ {
+ ERR << "Can't open file for reading: " << file << " (" << ::Fstrerror(fd) << ")" << endl;
+ if ( fd )
+ ::Fclose( fd );
+ return RpmDb::CHK_ERROR;
+ }
+ rpmts ts = ::rpmtsCreate();
+ ::rpmtsSetRootDir( ts, root_r.c_str() );
+ ::rpmtsSetVSFlags( ts, RPMVSF_DEFAULT );
+
+ rpmQVKArguments_s qva;
+ memset( &qva, 0, sizeof(rpmQVKArguments_s) );
+ qva.qva_flags = (VERIFY_DIGEST|VERIFY_SIGNATURE);
+
+ RpmlogCapture vresult;
+ LocaleGuard guard( LC_ALL, "C" ); // bsc#1076415: rpm log output is localized, but we need to parse it :(
+ int res = ::rpmVerifySignatures( &qva, ts, fd, path_r.basename().c_str() );
+ guard.restore();
+
+ ts = rpmtsFree(ts);
+ ::Fclose( fd );
+
+ // results per line...
+ // Header V3 RSA/SHA256 Signature, key ID 3dbdc284: OK
+ // Header SHA1 digest: OK (a60386347863affefef484ff1f26c889373eb094)
+ // V3 RSA/SHA256 Signature, key ID 3dbdc284: OK
+ // MD5 digest: OK (fd5259fe677a406951dcb2e9d08c4dcc)
+ //
+ // TODO: try to get SIG info from the header rather than parsing the output
+ std::vector<std::string> lines;
+ str::split( vresult, std::back_inserter(lines), "\n" );
+ unsigned count[7] = { 0, 0, 0, 0, 0, 0, 0 };
+
+ for ( unsigned i = 1; i < lines.size(); ++i )
+ {
+ std::string & line( lines[i] );
+ RpmDb::CheckPackageResult lineres = RpmDb::CHK_ERROR;
+ if ( line.find( ": OK" ) != std::string::npos )
+ {
+ lineres = RpmDb::CHK_OK;
+ if ( line.find( "Signature, key ID" ) == std::string::npos )
+ ++count[RpmDb::CHK_NOSIG]; // Valid but no gpg signature -> CHK_NOSIG
+ }
+ else if ( line.find( ": NOKEY" ) != std::string::npos )
+ { lineres = RpmDb::CHK_NOKEY; }
+ else if ( line.find( ": BAD" ) != std::string::npos )
+ { lineres = RpmDb::CHK_FAIL; }
+ else if ( line.find( ": UNKNOWN" ) != std::string::npos )
+ { lineres = RpmDb::CHK_NOTFOUND; }
+ else if ( line.find( ": NOTRUSTED" ) != std::string::npos )
+ { lineres = RpmDb::CHK_NOTTRUSTED; }
+
+ ++count[lineres];
+ detail_r.push_back( RpmDb::CheckPackageDetail::value_type( lineres, std::move(line) ) );
+ }
- RpmlogCapture vresult;
- LocaleGuard guard( LC_ALL, "C" ); // bsc#1076415: rpm log output is localized, but we need to parse it :(
- int res = ::rpmVerifySignatures( &qva, ts, fd, path_r.basename().c_str() );
- guard.restore();
+ RpmDb::CheckPackageResult ret = ( res ? RpmDb::CHK_ERROR : RpmDb::CHK_OK );
- ts = rpmtsFree(ts);
- ::Fclose( fd );
+ if ( count[RpmDb::CHK_FAIL] )
+ ret = RpmDb::CHK_FAIL;
+ else if ( count[RpmDb::CHK_NOTFOUND] )
+ ret = RpmDb::CHK_NOTFOUND;
- if ( res == 0 )
- {
- detail_r.push_back( CheckPackageDetail::value_type( CHK_OK, std::move(vresult) ) );
- return CHK_OK;
- }
+ else if ( count[RpmDb::CHK_NOKEY] )
+ ret = RpmDb::CHK_NOKEY;
- // results per line...
- WAR << vresult;
- std::vector<std::string> lines;
- str::split( vresult, std::back_inserter(lines), "\n" );
- unsigned count[6] = { 0, 0, 0, 0, 0, 0 };
+ else if ( count[RpmDb::CHK_NOTTRUSTED] )
+ ret = RpmDb::CHK_NOTTRUSTED;
- for ( unsigned i = 1; i < lines.size(); ++i )
- {
- std::string & line( lines[i] );
- CheckPackageResult lineres = CHK_ERROR;
- if ( line.find( ": OK" ) != std::string::npos )
- { lineres = CHK_OK; }
- else if ( line.find( ": NOKEY" ) != std::string::npos )
- { lineres = CHK_NOKEY; }
- else if ( line.find( ": BAD" ) != std::string::npos )
- { lineres = CHK_FAIL; }
- else if ( line.find( ": UNKNOWN" ) != std::string::npos )
- { lineres = CHK_NOTFOUND; }
- else if ( line.find( ": NOTRUSTED" ) != std::string::npos )
- { lineres = CHK_NOTTRUSTED; }
+ else if ( ret == RpmDb::CHK_OK )
+ {
+ if ( count[RpmDb::CHK_OK] == count[RpmDb::CHK_NOSIG] )
+ {
+ detail_r.push_back( RpmDb::CheckPackageDetail::value_type( RpmDb::CHK_NOSIG, std::string(" ")+_("Package is not signed!") ) );
+ if ( requireGPGSig_r )
+ ret = RpmDb::CHK_NOSIG;
+ }
+ }
- ++count[lineres];
- detail_r.push_back( CheckPackageDetail::value_type( lineres, std::move(line) ) );
+ if ( ret != RpmDb::CHK_OK )
+ {
+ WAR << path_r << " (" << requireGPGSig_r << " -> " << ret << ")" << endl;
+ WAR << vresult;
+ }
+ return ret;
}
- CheckPackageResult ret = CHK_ERROR;
- if ( count[CHK_FAIL] )
- ret = CHK_FAIL;
-
- else if ( count[CHK_NOTFOUND] )
- ret = CHK_NOTFOUND;
-
- else if ( count[CHK_NOKEY] )
- ret = CHK_NOKEY;
-
- else if ( count[CHK_NOTTRUSTED] )
- ret = CHK_NOTTRUSTED;
-
- return ret;
-}
+} // namespace
+///////////////////////////////////////////////////////////////////
+//
+// METHOD NAME : RpmDb::checkPackage
+// METHOD TYPE : RpmDb::CheckPackageResult
+//
+RpmDb::CheckPackageResult RpmDb::checkPackage( const Pathname & path_r, CheckPackageDetail & detail_r )
+{ return doCheckPackageSig( path_r, root(), false/*requireGPGSig_r*/, detail_r ); }
RpmDb::CheckPackageResult RpmDb::checkPackage( const Pathname & path_r )
{ CheckPackageDetail dummy; return checkPackage( path_r, dummy ); }
+RpmDb::CheckPackageResult RpmDb::checkPackageSignature( const Pathname & path_r, RpmDb::CheckPackageDetail & detail_r )
+{ return doCheckPackageSig( path_r, root(), true/*requireGPGSig_r*/, detail_r ); }
+
// determine changed files of installed package
bool
OUTS( CHK_NOKEY, _("Signatures public key is not available") );
// translators: possible rpm package signature check result [brief]
OUTS( CHK_ERROR, _("File does not exist or signature can't be checked") );
+ // translators: possible rpm package signature check result [brief]
+ OUTS( CHK_NOSIG, _("File is unsigned") );
#undef OUTS
}
return str << "UnknowSignatureCheckError("+str::numstring(obj)+")";