17#include <zypp-media/ng/Provide>
18#include <zypp-media/ng/ProvideSpec>
19#include <zypp/ng/Context>
20#include <zypp/ng/repo/Downloader>
21#include <zypp-common/PublicKey.h>
35#undef ZYPP_BASE_LOGGER_LOGGROUP
36#define ZYPP_BASE_LOGGER_LOGGROUP "zypp::repomanager"
44 template <
class Executor,
class OpType >
45 struct DownloadMasterIndexLogic :
public LogicBase<Executor, OpType>
52 using ProvideType =
typename ZyppContextType::ProvideType;
53 using MediaHandle =
typename ProvideType::MediaHandle;
57 : _dlContext( std::move(ctxRef) )
58 , _media(std::move( mediaHandle ))
59 , _masterIndex(std::move( masterIndex_r ))
63 MaybeAsyncRef<expected<DlContextRefType>> execute( ) {
67 _sigpath = _masterIndex.extend(
".asc" );
68 _keypath = _masterIndex.extend(
".key" );
69 _destdir = _dlContext->destDir();
71 auto providerRef = _dlContext->zyppContext()->provider();
81 |
and_then( ProvideType::copyResultToDest ( provider(), _destdir / _sigpath ) )
88 _dlContext->files().push_back( std::move(*sigFile) );
92 if ( expKeyId && !_dlContext->zyppContext()->keyRing()->isKeyKnown(*expKeyId) ) {
94 bool needsMirrorToFetchKey = _dlContext->repoInfo().baseUrlsEmpty() && _dlContext->repoInfo().mirrorListUrl().isValid() ;
95 if ( needsMirrorToFetchKey ) {
98 JobReportHelper( _dlContext->zyppContext() ).
warning(
_(
"Downloading signature key via mirrors, consider explicitely setting gpgKeyUrl via the repository configuration instead."));
103 |
and_then( ProvideType::copyResultToDest ( provider(), _destdir / _keypath ) )
105 _dlContext->files().push_back( std::move(keyFile));
120 |
and_then( std::bind( &DownloadMasterIndexLogic::pluginVerification,
this, std::placeholders::_1 ) )
123 |
and_then( std::bind( &DownloadMasterIndexLogic::signatureCheck,
this, std::placeholders::_1 ) )
126 |
and_then( ProvideType::copyResultToDest ( providerRef, _destdir / _masterIndex ) )
131 _dlContext->repoInfo().setMetadataPath( _destdir );
132 _dlContext->repoInfo().setValidRepoSignature( _repoSigValidated );
135 _media = MediaHandle();
136 auto &allFiles = _dlContext->files();
139 allFiles.insert( allFiles.begin (), std::move(masterIndex) );
147 return _dlContext->zyppContext()->provider();
150 MaybeAsyncRef<expected<ProvideRes>> signatureCheck (
ProvideRes &&res ) {
152 if ( _dlContext->repoInfo().repoGpgCheck() ) {
159 if ( isSigned || _dlContext->repoInfo().repoGpgCheckIsMandatory() ) {
165 verifyCtx.signature( sigpathLocal );
170 _dlContext->zyppContext()->keyRing()->importKey( zypp::PublicKey(keypathLocal),
false );
178 verifyCtx.keyContext( _dlContext->repoInfo() );
180 return getExtraKeysInRepomd( std::move(res ) )
182 for (
const auto &keyData : _buddyKeys ) {
183 DBG <<
"Keyhint remember buddy " << keyData << std::endl;
184 vCtx.addBuddyKey( keyData.id() );
196 WAR <<
"Accept unsigned repository because repoGpgCheck is not mandatory for " << _dlContext->repoInfo().alias() << std::endl;
199 WAR <<
"Signature checking disabled in config of repository " << _dlContext->repoInfo().alias() << std::endl;
210 if ( _dlContext->pluginRepoverification() && _dlContext->pluginRepoverification()->isNeeded() ) {
214 auto kr = _dlContext->zyppContext()->keyRing();
218 MIL <<
"Failed to read signature from file: " << sigpathLocal << std::endl;
220 std::ofstream os( keypathLocal.
c_str() );
221 if ( kr->isKeyKnown(*expKeyId) ) {
224 kr->isKeyTrusted(*expKeyId),
231 _dlContext->pluginRepoverification()->getChecker( sigpathLocal, keypathLocal, _dlContext->repoInfo() )( prevRes.file() );
243 MaybeAsyncRef<expected<ProvideRes>> getExtraKeysInRepomd (
ProvideRes &&res ) {
245 if ( _masterIndex.basename() !=
"repomd.xml" ) {
250 if ( keyhints.empty() )
252 DBG <<
"Check keyhints: " << keyhints.size() << std::endl;
254 auto keyRing { _dlContext->zyppContext()->keyRing() };
256 |
transform([
this, keyRing]( std::pair<std::string, std::string> val ) {
258 const auto& [ file, keyid ] = val;
259 auto keyData = keyRing->trustedPublicKeyData( keyid );
261 DBG <<
"Keyhint is already trusted: " << keyid <<
" (" << file <<
")" << std::endl;
265 DBG <<
"Keyhint search key " << keyid <<
" (" << file <<
")" << std::endl;
267 keyData = keyRing->publicKeyData( keyid );
272 const zypp::ZConfig & conf = _dlContext->zyppContext()->config();
275 return zypp::PublicKey::noThrow(cacheFile)
276 | [ keyid = keyid ](
auto &&key ){
277 if ( key.fileProvidesKey( keyid ) )
283 auto providerRef = _dlContext->zyppContext()->provider();
284 return providerRef->provide( _media, file,
ProvideFileSpec().setOptional(
true).setMirrorsAllowed(
false) )
285 |
and_then( ProvideType::copyResultToDest( providerRef, _destdir / file ) )
289 _dlContext->files().push_back ( std::move(res) );
291 auto key = zypp::PublicKey::noThrow( _dlContext->files().back() );
292 if ( not key.fileProvidesKey( keyid ) ) {
293 const std::string
str = (
zypp::str::Str() <<
"Keyhint " << file <<
" does not contain a key with id " << keyid <<
". Skipping it.");
300 return providerRef->copyFile( key.path(), cacheFile )
304 res->resetDispose ();
310 |
and_then( [ keyRing, keyid = keyid ]( zypp::PublicKey key ){
311 keyRing->importKey( key,
false );
317 if ( keyData && *keyData ) {
318 if ( not zypp::PublicKey::isSafeKeyId( keyData->id() ) ) {
319 WAR <<
"Keyhint " << keyData->id() <<
" for " << *keyData <<
" is not strong enough for auto import. Just caching it." << std::endl;
322 _buddyKeys.push_back ( std::move(keyData.get()) );
326 MIL <<
"Check keyhints done. Buddy keys: " << _buddyKeys.size() << std::endl;
331 DlContextRefType _dlContext;
340 std::vector<zypp::PublicKeyData> _buddyKeys;
358 return dl->zyppContext()->provider()->attachMediaIfNeeded( mediaHandle )
367 return dl->zyppContext()->provider()->attachMediaIfNeeded( mediaHandle )
375 template <
class DlContextRefType,
class MediaHandleType>
376 auto statusImpl ( DlContextRefType dlCtx, MediaHandleType &&mediaHandle ) {
378 constexpr bool isAsync = std::is_same_v<DlContextRefType,repo::AsyncDownloadContextRef>;
384 switch( dlCtx->repoInfo().type().toEnum()) {
400 return statusImpl( dl, std::move(mediaHandle) );
404 return statusImpl( dl, std::move(mediaHandle) );
409 return dl->zyppContext()->provider()->attachMediaIfNeeded( mediaHandle )
417 return dl->zyppContext()->provider()->attachMediaIfNeeded( mediaHandle )
425 template <
class DlContextRefType,
class MediaHandleType>
426 auto downloadImpl ( DlContextRefType dlCtx, MediaHandleType &&mediaHandle, ProgressObserverRef &&progressObserver ) {
428 constexpr bool isAsync = std::is_same_v<DlContextRefType,repo::AsyncDownloadContextRef>;
430 switch( dlCtx->repoInfo().type().toEnum()) {
432 return RpmmdWorkflows::download( std::move(dlCtx), std::forward<MediaHandleType>(mediaHandle), std::move(progressObserver) );
447 return downloadImpl( dl, std::move(mediaHandle), std::move(progressObserver) );
452 return downloadImpl( dl, std::move(mediaHandle), std::move(progressObserver) );
458 return dl->zyppContext()->provider()->attachMediaIfNeeded( mediaHandle )
460 return downloadImpl( dl, std::move(handle), std::move(po) );
467 return dl->zyppContext()->provider()->attachMediaIfNeeded( mediaHandle )
469 return downloadImpl( dl, std::move(handle), std::move(po) );
Interface of repomd.xml file reader.
Store and operate with byte count.
static const Unit MB
1000^2 Byte
Base class for Exception.
std::string readSignatureKeyId(const Pathname &signature)
reads the public key id from a signature
What is known about a repository.
Track changing files or directories.
Interim helper class to collect global options and settings.
Pathname repoManagerRoot() const
The RepoManager root directory.
Pathname pubkeyCachePath() const
Path where the pubkey caches.
Wrapper class for stat/lstat.
bool isExist() const
Return whether valid stat info exists.
Pathname dirname() const
Return all but the last component od this path.
const char * c_str() const
String representation.
I/O context for KeyRing::verifyFileSignatureWorkflow.
bool fileValidated() const
Whether the signature was actually successfully verified.
Reads through a repomd.xml file and collects type, location, checksum and other data about metadata f...
std::vector< std::pair< std::string, std::string > > keyhints() const
gpg key hits shipped in keywords (bsc#1184326)
thrown when it was impossible to determine this repo type.
bool warning(std::string msg_r, UserData userData_r=UserData())
send warning text
A ProvideRes object is a reference counted ownership of a resource in the cache provided by a Provide...
static expected success(ConsParams &&...params)
static expected error(ConsParams &&...params)
boost::logic::tribool TriBool
3-state boolean logic (true, false and indeterminate).
#define ZYPP_ENABLE_LOGIC_BASE(Executor, OpType)
typename conditional< B, T, F >::type conditional_t
String related utilities and Regular expression matching.
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
AutoDispose< const Pathname > ManagedFile
A Pathname plus associated cleanup code to be executed when path is no longer needed.
AsyncOpRef< expected< repo::AsyncDownloadContextRef > > download(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle, ProgressObserverRef progressObserver)
AsyncOpRef< expected< zypp::RepoStatus > > repoStatus(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle)
AsyncOpRef< expected< repo::AsyncDownloadContextRef > > download(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle, ProgressObserverRef progressObserver=nullptr)
AsyncOpRef< expected< repo::AsyncDownloadContextRef > > downloadMasterIndex(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle, zypp::filesystem::Pathname masterIndex_r)
AsyncOpRef< expected< zypp::RepoStatus > > repoStatus(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle)
expected< void > fetchGpgKeys(SyncContextRef ctx, zypp::RepoInfo info)
AsyncOpRef< expected< repo::AsyncDownloadContextRef > > download(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle, ProgressObserverRef progressObserver)
AsyncOpRef< expected< zypp::RepoStatus > > repoStatus(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle)
expected< zypp::keyring::VerifyFileContext > verifySignature(SyncContextRef ctx, zypp::keyring::VerifyFileContext context)
auto and_then(Fun &&function)
Exp mtry(F &&f, Args &&...args)
std::conditional_t< isAsync, AsyncOpRef< T >, T > makeReadyResult(T &&result)
std::shared_ptr< AsyncOp< T > > AsyncOpRef
typename remove_smart_ptr< T >::type remove_smart_ptr_t
static expected< std::decay_t< Type >, Err > make_expected_success(Type &&t)
LazyMediaHandle< Provide > AsyncLazyMediaHandle
ResultType or_else(const expected< T, E > &exp, Function &&f)
ResultType and_then(const expected< T, E > &exp, Function &&f)
LazyMediaHandle< MediaSyncFacade > SyncLazyMediaHandle
Container< Ret > transform(Container< Msg, CArgs... > &&val, Transformation &&transformation)
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
#define ZYPP_EXCPT_PTR(EXCPT)
Drops a logline and returns Exception as a std::exception_ptr.
#define ZYPP_FWD_CURRENT_EXCPT()
Drops a logline and returns the current Exception as a std::exception_ptr.