15 #include <zypp-media/ng/ProvideSpec> 21 #include <zypp/ng/Context> 22 #include <zypp/ng/media/Provide> 23 #include <zypp/ng/repo/Downloader> 38 #undef ZYPP_BASE_LOGGER_LOGGROUP 39 #define ZYPP_BASE_LOGGER_LOGGROUP "zypp::repomanager" 47 struct DownloadMasterIndexLogic
53 DownloadMasterIndexLogic( repo::DownloadContextRef &&ctxRef, MediaHandle &&mediaHandle,
zypp::filesystem::Pathname &&masterIndex_r )
55 ,
_media(std::move( mediaHandle ))
60 MaybeAwaitable<expected<repo::DownloadContextRef>> execute( ) {
68 static const std::string rinfoSigcheckTag {
"repo_sigcheck_plugin" };
82 auto providerRef =
_dlContext->zyppContext()->provider();
94 | [
this]( expected<zypp::ManagedFile> sigFile ) {
99 _dlContext->files().push_back( std::move(*sigFile) );
103 if ( expKeyId && !
_dlContext->zyppContext()->keyRing()->isKeyKnown(*expKeyId) ) {
105 bool needsMirrorToFetchKey =
_dlContext->repoInfo().baseUrlsEmpty() &&
_dlContext->repoInfo().mirrorListUrl().isValid() ;
106 if ( needsMirrorToFetchKey ) {
109 JobReportHelper(
_dlContext->zyppContext() ).warning(
_(
"Downloading signature key via mirrors, consider explicitly setting gpgKeyUrl via the repository configuration instead."));
117 _dlContext->files().push_back( std::move(keyFile));
126 | [masterres=std::move(masterres)]( expected<void> ) {
140 |
and_then( std::bind( &DownloadMasterIndexLogic::pluginVerification,
this ) )
143 |
and_then( std::bind( &DownloadMasterIndexLogic::executeSigcheckPlugins,
this ) )
146 |
and_then( std::bind( &DownloadMasterIndexLogic::signatureCheck,
this ) )
166 ProvideRef provider () {
170 MaybeAwaitable<expected<void>> executeSigcheckPlugins()
180 auto * pluginPtr = &plugin;
181 for (
const auto & ext : { plugin.sigExtension(), plugin.keyExtension() } ) {
189 return provider()->provide(
_media, extpath, ProvideFileSpec().setOptional(
false ).setMirrorsAllowed(
false ) )
192 _dlContext->files().push_back( std::move(downloaded_r) );
202 if ( not pluginPtr->sigExtension().empty() ) {
206 if ( not pluginPtr->keyExtension().empty() ) {
210 pluginPtr->sigcheck( masterIndexLocal, sig, key );
221 MaybeAwaitable<expected<void>> signatureCheck () {
223 if (
_dlContext->repoInfo().repoGpgCheck() ) {
231 if ( isSigned ||
_dlContext->repoInfo().repoGpgCheckIsMandatory() ) {
237 verifyCtx.signature( sigpathLocal );
250 verifyCtx.keyContext(
_dlContext->repoInfo() );
252 return getExtraKeysInRepomd()
253 |
and_then([
this, vCtx = std::move(verifyCtx) ]()
mutable {
255 DBG <<
"Keyhint remember buddy " << keyData << std::endl;
256 vCtx.addBuddyKey( keyData.id() );
268 WAR <<
"Accept unsigned repository because repoGpgCheck is not mandatory for " <<
_dlContext->repoInfo().alias() << std::endl;
271 WAR <<
"Signature checking disabled in config of repository " <<
_dlContext->repoInfo().alias() << std::endl;
277 expected<void> pluginVerification () {
283 if (
_dlContext->pluginRepoverification() &&
_dlContext->pluginRepoverification()->isNeeded() ) {
287 auto kr =
_dlContext->zyppContext()->keyRing();
291 MIL <<
"Failed to read signature from file: " << sigpathLocal << std::endl;
293 std::ofstream os( keypathLocal.c_str() );
294 if ( kr->isKeyKnown(*expKeyId) ) {
297 kr->isKeyTrusted(*expKeyId),
304 _dlContext->pluginRepoverification()->getChecker( sigpathLocal, keypathLocal,
_dlContext->repoInfo() )( masterIndexLocal );
316 MaybeAwaitable<expected<void>> getExtraKeysInRepomd () {
324 if ( keyhints.empty() )
326 DBG <<
"Check keyhints: " << keyhints.size() << std::endl;
328 auto keyRing {
_dlContext->zyppContext()->keyRing() };
329 return std::move( keyhints )
330 |
transform( [
this, keyRing]( std::pair<std::string, std::string> val ) {
332 const auto& [ file, keyid ] = val;
333 auto keyData = keyRing->trustedPublicKeyData( keyid );
335 DBG <<
"Keyhint is already trusted: " << keyid <<
" (" << file <<
")" << std::endl;
339 DBG <<
"Keyhint search key " << keyid <<
" (" << file <<
")" << std::endl;
341 keyData = keyRing->publicKeyData( keyid );
350 | [ keyid = keyid ](
auto &&key ){
351 if ( key.fileProvidesKey( keyid ) )
356 |
or_else ([
this, file = file, keyid = keyid, cacheFile ] (
auto )
mutable -> MaybeAwaitable<expected<zypp::PublicKey>> {
357 auto providerRef =
_dlContext->zyppContext()->provider();
358 return providerRef->provide(
_media, file, ProvideFileSpec().setOptional(
true).setMirrorsAllowed(
false) )
363 _dlContext->files().push_back ( std::move(res) );
366 if ( not key.fileProvidesKey( keyid ) ) {
367 const std::string
str = (
zypp::str::Str() <<
"Keyhint " << file <<
" does not contain a key with id " << keyid <<
". Skipping it.");
374 return providerRef->copyFile( key.path(), cacheFile )
375 | [ key ]( expected<zypp::ManagedFile> res )
mutable {
378 res->resetDispose ();
385 keyRing->importKey( key,
false );
389 | [
this] ( std::vector<expected<zypp::PublicKeyData>> &&keyHints )
mutable {
390 std::for_each( keyHints.begin(), keyHints.end(), [
this]( expected<zypp::PublicKeyData> &keyData ){
391 if ( keyData && *keyData ) {
393 WAR <<
"Keyhint " << keyData->id() <<
" for " << *keyData <<
" is not strong enough for auto import. Just caching it." << std::endl;
396 _buddyKeys.push_back ( std::move(keyData.get()) );
400 MIL <<
"Check keyhints done. Buddy keys: " <<
_buddyKeys.size() << std::endl;
424 DownloadMasterIndexLogic impl( std::move(dl), std::move(mediaHandle), std::move(masterIndex_r) );
425 zypp_co_return zypp_co_await( impl.execute() );
431 return dl->zyppContext()->provider()->attachMediaIfNeeded( mediaHandle )
439 auto statusImpl ( repo::DownloadContextRef dlCtx,
ProvideMediaHandle &&mediaHandle ) {
444 switch( dlCtx->repoInfo().type().toEnum()) {
460 return statusImpl( dl, std::move(mediaHandle) );
465 return dl->zyppContext()->provider()->attachMediaIfNeeded( mediaHandle )
472 auto downloadImpl ( repo::DownloadContextRef dlCtx,
ProvideMediaHandle &&mediaHandle, ProgressObserverRef &&progressObserver ) {
473 switch( dlCtx->repoInfo().type().toEnum()) {
475 return RpmmdWorkflows::download( std::move(dlCtx), std::forward<ProvideMediaHandle>(mediaHandle), std::move(progressObserver) );
477 return SuseTagsWorkflows::download( std::move(dlCtx), std::forward<ProvideMediaHandle>(mediaHandle), std::move(progressObserver) );
490 return downloadImpl( dl, std::move(mediaHandle), std::move(progressObserver) );
496 return dl->zyppContext()->provider()->attachMediaIfNeeded( mediaHandle )
498 return downloadImpl( dl, std::move(handle), std::move(po) );
bool fileValidated() const
Whether the signature was actually successfully verified.
auto mtry(Fun &&function)
thrown when it was impossible to determine this repo type.
auto transform(Transformation &&transformation)
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
MaybeAwaitable< expected< repo::DownloadContextRef > > downloadMasterIndex(repo::DownloadContextRef dl, ProvideMediaHandle mediaHandle, zypp::filesystem::Pathname masterIndex_r)
MaybeAwaitable< expected< void > > fetchGpgKeys(ContextRef ctx, zypp::RepoInfo info)
Store and operate with byte count.
Pathname pubkeyCachePath() const
Path where the pubkey caches.
Pathname extend(const std::string &r) const
Append string r to the last component of the path.
zypp::ManagedFile _masterIndexFile
zypp::Pathname _masterIndex
String related utilities and Regular expression matching.
zypp::TriBool _repoSigValidated
What is known about a repository.
static expected< std::decay_t< Type >, Err > make_expected_success(Type &&t)
I/O context for KeyRing::verifyFileSignatureWorkflow.
static const Unit MB
1000^2 Byte
std::string basename() const
Return the last component of this path.
repo::DownloadContextRef _dlContext
#define ZYPP_EXCPT_PTR(EXCPT)
Drops a logline and returns Exception as a std::exception_ptr.
MaybeAwaitable< expected< repo::DownloadContextRef > > download(repo::DownloadContextRef dl, ProvideMediaHandle mediaHandle, ProgressObserverRef progressObserver)
const Plugins & plugins()
All plugins (their addresses can be captured).
MaybeAwaitable< expected< repo::DownloadContextRef > > download(repo::DownloadContextRef dl, ProvideMediaHandle mediaHandle, ProgressObserverRef progressObserver)
boost::logic::tribool TriBool
3-state boolean logic (true, false and indeterminate).
std::string extraValue(const std::string &key_r) const
Return extra value for key_r or throws std::out_of_range.
Pathname repoManagerRoot() const
The RepoManager root directory.
auto or_else(Fun &&function)
zypp::SigcheckPlugins _sigcheckPlugins
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
std::vector< std::pair< std::string, std::string > > keyhints() const
gpg key hits shipped in keywords (bsc#1184326)
bool isExist() const
Return whether valid stat info exists.
Pathname dirname() const
Return all but the last component od this path.
Interim helper class to collect global options and settings.
bool hasExtraValue(const std::string &key_r) const
Whether an extra value for key_r is set.
ProvideMediaHandle MediaHandle
MaybeAwaitable< expected< zypp::keyring::VerifyFileContext > > verifySignature(ContextRef ctx, zypp::keyring::VerifyFileContext context)
static expected success(ConsParams &&...params)
MaybeAwaitable< expected< zypp::RepoStatus > > repoStatus(repo::DownloadContextRef dl, ProvideMediaHandle mediaHandle)
MaybeAwaitable< expected< repo::DownloadContextRef > > download(repo::DownloadContextRef dl, ProvideMediaHandle mediaHandle, ProgressObserverRef progressObserver=nullptr)
void launch(const Pathname &chroot_r=Pathname())
Launch all plugins (optionally chrooted).
Class representing one GPG Public Key (PublicKeyData + ASCII armored in a tempfile).
Reads through a repomd.xml file and collects type, location, checksum and other data about metadata f...
Base class for Exception.
static bool isSafeKeyId(const std::string &id_r)
!<
auto and_then(Fun &&function)
Chain< TACondition, TBCondition > chain(TACondition conda_r, TBCondition condb_r)
Convenience function for creating a Chain from two conditions conda_r and condb_r.
Wrapper class for ::stat/::lstat.
Interface of repomd.xml file reader.
ResultType and_then(const expected< T, E > &exp, Function &&f)
MaybeAwaitable< expected< zypp::RepoStatus > > repoStatus(repo::DownloadContextRef dl, ProvideMediaHandle mediaHandle)
Track changing files or directories.
static PublicKey noThrow(const Pathname &keyFile_r)
Static ctor returning an empty PublicKey rather than throwing.
#define ZYPP_FWD_CURRENT_EXCPT()
Drops a logline and returns the current Exception as a std::exception_ptr.
MaybeAwaitable< expected< zypp::RepoStatus > > repoStatus(repo::DownloadContextRef dl, ProvideMediaHandle mediaHandle)
std::string readSignatureKeyId(const Pathname &signature)
reads the public key id from a signature
static auto copyResultToDest(ProvideRef provider, const zypp::Pathname &targetPath)
Handle a bunch of SigcheckPlugins.
std::vector< zypp::PublicKeyData > _buddyKeys