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)
#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.
boost::logic::tribool TriBool
3-state boolean logic (true, false and indeterminate).
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.