15#include <zypp-media/ng/ProvideSpec>
20#include <zypp/ng/Context>
21#include <zypp/ng/media/Provide>
22#include <zypp/ng/repo/Downloader>
36#undef ZYPP_BASE_LOGGER_LOGGROUP
37#define ZYPP_BASE_LOGGER_LOGGROUP "zypp::repomanager"
45 struct DownloadMasterIndexLogic
51 DownloadMasterIndexLogic( repo::DownloadContextRef &&ctxRef, MediaHandle &&mediaHandle,
zypp::filesystem::Pathname &&masterIndex_r )
52 : _dlContext( std::move(ctxRef) )
53 , _media(std::move( mediaHandle ))
54 , _masterIndex(std::move( masterIndex_r ))
58 MaybeAwaitable<expected<repo::DownloadContextRef>> execute( ) {
62 _sigpath = _masterIndex.extend(
".asc" );
63 _keypath = _masterIndex.extend(
".key" );
64 _destdir = _dlContext->destDir();
66 auto providerRef = _dlContext->zyppContext()->provider();
83 _dlContext->files().push_back( std::move(*sigFile) );
87 if ( expKeyId && !_dlContext->zyppContext()->keyRing()->isKeyKnown(*expKeyId) ) {
89 bool needsMirrorToFetchKey = _dlContext->repoInfo().baseUrlsEmpty() && _dlContext->repoInfo().mirrorListUrl().isValid() ;
90 if ( needsMirrorToFetchKey ) {
93 JobReportHelper( _dlContext->zyppContext() ).
warning(
_(
"Downloading signature key via mirrors, consider explicitely setting gpgKeyUrl via the repository configuration instead."));
100 _dlContext->files().push_back( std::move(keyFile));
115 |
and_then( std::bind( &DownloadMasterIndexLogic::pluginVerification,
this, std::placeholders::_1 ) )
118 |
and_then( std::bind( &DownloadMasterIndexLogic::signatureCheck,
this, std::placeholders::_1 ) )
126 _dlContext->repoInfo().setMetadataPath( _destdir );
127 _dlContext->repoInfo().setValidRepoSignature( _repoSigValidated );
130 _media = MediaHandle();
131 auto &allFiles = _dlContext->files();
134 allFiles.insert( allFiles.begin (), std::move(masterIndex) );
141 ProvideRef provider () {
142 return _dlContext->zyppContext()->provider();
145 MaybeAwaitable<expected<ProvideRes>> signatureCheck (
ProvideRes &&res ) {
147 if ( _dlContext->repoInfo().repoGpgCheck() ) {
154 if ( isSigned || _dlContext->repoInfo().repoGpgCheckIsMandatory() ) {
160 verifyCtx.signature( sigpathLocal );
165 _dlContext->zyppContext()->keyRing()->importKey(
zypp::PublicKey(keypathLocal),
false );
173 verifyCtx.keyContext( _dlContext->repoInfo() );
175 return getExtraKeysInRepomd( std::move(res ) )
177 for (
const auto &keyData : _buddyKeys ) {
178 DBG <<
"Keyhint remember buddy " << keyData << std::endl;
179 vCtx.addBuddyKey( keyData.id() );
191 WAR <<
"Accept unsigned repository because repoGpgCheck is not mandatory for " << _dlContext->repoInfo().alias() << std::endl;
194 WAR <<
"Signature checking disabled in config of repository " << _dlContext->repoInfo().alias() << std::endl;
205 if ( _dlContext->pluginRepoverification() && _dlContext->pluginRepoverification()->isNeeded() ) {
209 auto kr = _dlContext->zyppContext()->keyRing();
213 MIL <<
"Failed to read signature from file: " << sigpathLocal << std::endl;
215 std::ofstream os( keypathLocal.
c_str() );
216 if ( kr->isKeyKnown(*expKeyId) ) {
219 kr->isKeyTrusted(*expKeyId),
226 _dlContext->pluginRepoverification()->getChecker( sigpathLocal, keypathLocal, _dlContext->repoInfo() )( prevRes.file() );
238 MaybeAwaitable<expected<ProvideRes>> getExtraKeysInRepomd (
ProvideRes &&res ) {
240 if ( _masterIndex.basename() !=
"repomd.xml" ) {
245 if ( keyhints.empty() )
247 DBG <<
"Check keyhints: " << keyhints.size() << std::endl;
249 auto keyRing { _dlContext->zyppContext()->keyRing() };
251 |
transform( [
this, keyRing]( std::pair<std::string, std::string> val ) {
253 const auto& [ file, keyid ] = val;
254 auto keyData = keyRing->trustedPublicKeyData( keyid );
256 DBG <<
"Keyhint is already trusted: " << keyid <<
" (" << file <<
")" << std::endl;
260 DBG <<
"Keyhint search key " << keyid <<
" (" << file <<
")" << std::endl;
262 keyData = keyRing->publicKeyData( keyid );
267 const zypp::ZConfig & conf = _dlContext->zyppContext()->config();
271 | [ keyid = keyid ](
auto &&key ){
272 if ( key.fileProvidesKey( keyid ) )
278 auto providerRef = _dlContext->zyppContext()->provider();
279 return providerRef->provide( _media, file,
ProvideFileSpec().setOptional(
true).setMirrorsAllowed(
false) )
284 _dlContext->files().push_back ( std::move(res) );
287 if ( not key.fileProvidesKey( keyid ) ) {
288 const std::string
str = (
zypp::str::Str() <<
"Keyhint " << file <<
" does not contain a key with id " << keyid <<
". Skipping it.");
295 return providerRef->copyFile( key.path(), cacheFile )
299 res->resetDispose ();
306 keyRing->importKey( key,
false );
312 if ( keyData && *keyData ) {
313 if ( not zypp::PublicKey::isSafeKeyId( keyData->id() ) ) {
314 WAR <<
"Keyhint " << keyData->id() <<
" for " << *keyData <<
" is not strong enough for auto import. Just caching it." << std::endl;
317 _buddyKeys.push_back ( std::move(keyData.get()) );
321 MIL <<
"Check keyhints done. Buddy keys: " << _buddyKeys.size() << std::endl;
326 repo::DownloadContextRef _dlContext;
335 std::vector<zypp::PublicKeyData> _buddyKeys;
342 DownloadMasterIndexLogic impl( std::move(dl), std::move(mediaHandle), std::move(masterIndex_r) );
343 zypp_co_return zypp_co_await( impl.execute() );
349 return dl->zyppContext()->provider()->attachMediaIfNeeded( mediaHandle )
357 auto statusImpl ( repo::DownloadContextRef dlCtx,
ProvideMediaHandle &&mediaHandle ) {
362 switch( dlCtx->repoInfo().type().toEnum()) {
378 return statusImpl( dl, std::move(mediaHandle) );
383 return dl->zyppContext()->provider()->attachMediaIfNeeded( mediaHandle )
390 auto downloadImpl ( repo::DownloadContextRef dlCtx,
ProvideMediaHandle &&mediaHandle, ProgressObserverRef &&progressObserver ) {
391 switch( dlCtx->repoInfo().type().toEnum()) {
393 return RpmmdWorkflows::download( std::move(dlCtx), std::forward<ProvideMediaHandle>(mediaHandle), std::move(progressObserver) );
395 return SuseTagsWorkflows::download( std::move(dlCtx), std::forward<ProvideMediaHandle>(mediaHandle), std::move(progressObserver) );
408 return downloadImpl( dl, std::move(mediaHandle), std::move(progressObserver) );
414 return dl->zyppContext()->provider()->attachMediaIfNeeded( mediaHandle )
416 return downloadImpl( dl, std::move(handle), std::move(po) );
#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.
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
Class representing one GPG Public Key (PublicKeyData + ASCII armored in a tempfile).
static PublicKey noThrow(const Pathname &keyFile_r)
Static ctor returning an empty PublicKey rather than throwing.
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
static auto copyResultToDest(ProvideRef provider, const zypp::Pathname &targetPath)
ProvideMediaHandle MediaHandle
static expected success(ConsParams &&...params)
static expected error(ConsParams &&...params)
boost::logic::tribool TriBool
3-state boolean logic (true, false and indeterminate).
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.
MaybeAwaitable< expected< repo::DownloadContextRef > > download(repo::DownloadContextRef dl, ProvideMediaHandle mediaHandle, ProgressObserverRef progressObserver)
MaybeAwaitable< expected< zypp::RepoStatus > > repoStatus(repo::DownloadContextRef dl, ProvideMediaHandle mediaHandle)
MaybeAwaitable< expected< zypp::RepoStatus > > repoStatus(repo::DownloadContextRef dl, ProvideMediaHandle mediaHandle)
MaybeAwaitable< expected< repo::DownloadContextRef > > download(repo::DownloadContextRef dl, ProvideMediaHandle mediaHandle, ProgressObserverRef progressObserver=nullptr)
MaybeAwaitable< expected< repo::DownloadContextRef > > downloadMasterIndex(repo::DownloadContextRef dl, ProvideMediaHandle mediaHandle, zypp::filesystem::Pathname masterIndex_r)
MaybeAwaitable< expected< void > > fetchGpgKeys(ContextRef ctx, zypp::RepoInfo info)
MaybeAwaitable< expected< repo::DownloadContextRef > > download(repo::DownloadContextRef dl, ProvideMediaHandle mediaHandle, ProgressObserverRef progressObserver)
MaybeAwaitable< expected< zypp::RepoStatus > > repoStatus(repo::DownloadContextRef dl, ProvideMediaHandle mediaHandle)
MaybeAwaitable< expected< zypp::keyring::VerifyFileContext > > verifySignature(ContextRef ctx, zypp::keyring::VerifyFileContext context)
auto and_then(Fun &&function)
static expected< std::decay_t< Type >, Err > make_expected_success(Type &&t)
ResultType or_else(const expected< T, E > &exp, Function &&f)
ResultType and_then(const expected< T, E > &exp, Function &&f)
auto transform(Container< Msg, CArgs... > &&val, Transformation &&transformation)
auto mtry(F &&f, Args &&...args)
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...