18#include <zypp-common/PublicKey.h> 
   22#include <zypp-core/zyppng/pipelines/Transform> 
   23#include <zypp-core/zyppng/pipelines/Expected> 
   24#include <zypp-core/zyppng/pipelines/MTry> 
   25#include <zypp-media/ng/Provide> 
   26#include <zypp-media/ng/ProvideSpec> 
   28#include <zypp/ng/Context> 
   29#include <zypp/ng/UserRequest> 
   39    using namespace zyppng::operators;
 
   41    template<
class Executor, 
class OpType>
 
   42    struct RepoInfoProvideKeyLogic : 
public LogicBase<Executor, OpType> {
 
   44      using ZyppContextRefType = MaybeAsyncContextRef<OpType>;
 
   46      using ProvideType     = 
typename ZyppContextType::ProvideType;
 
   47      using MediaHandle     = 
typename ProvideType::MediaHandle;
 
   48      using ProvideRes      = 
typename ProvideType::Res;
 
   50      RepoInfoProvideKeyLogic( ZyppContextRefType &&zyppContext, zypp::RepoInfo &&info, std::string &&keyID_r, zypp::Pathname &&targetDirectory_r )
 
   51        : _reports( std::move(zyppContext ))
 
   52        , _info( std::move(info) )
 
   53        , _keyID_r(std::move( keyID_r ))
 
   54        , _targetDirectory_r(std::move( targetDirectory_r ))
 
   55        , _keyIDStr( _keyID_r.size() > 8 ? _keyID_r.substr( _keyID_r.size()-8 ) : _keyID_r )    
 
   56        , _tempKeyRing( _tmpKeyRingDir )
 
   61      MaybeAsyncRef<zypp::filesystem::Pathname> execute () {
 
   62        using namespace zyppng::operators;
 
   63        using zyppng::operators::operator|;
 
   64        using zyppng::expected;
 
   67        if ( _keyID_r.empty() )
 
   70        importKeysInTargetDir();
 
   72        if ( _tempKeyRing.isKeyTrusted( _keyID_r) ) {
 
   76        if (  _info.gpgKeyUrlsEmpty() ) {
 
   78          _reports.info( zypp::str::Format(
_(
"Repository %1% does not define additional 'gpgkey=' URLs.") ) % _info.asUserString() );
 
   87        _reports.info( zypp::str::Format(
_(
"Looking for gpg key ID %1% in repository %2%.") ) %  _keyIDStr % _info.asUserString() );
 
   89        return _info.gpgKeyUrls()
 
   90         | 
transform( [
this]( 
const zypp::Url &url ) {
 
   92            _reports.info( 
"  gpgkey=" + url.
asString() );
 
   93            return fetchKey( url )
 
   97                      return expected<void>::error(std::make_exception_ptr( zypp::Exception(
"Empty ManagedFile returned.") ));
 
   99                    zypp::PublicKey key(f);
 
  100                    if ( !key.isValid() )
 
  104                    _tempKeyRing.multiKeyImport(f, 
true);
 
  106                  } 
catch ( 
const std::exception & e ) {
 
  109                    MIL << 
"Key import from url:'"<<url<<
"' failed." << std::endl;
 
  117         | [
this]( std::list<expected<void>> && ) ->zypp::Pathname {
 
  118              return writeKeysToTargetDir();
 
  124      MaybeAsyncRef<zyppng::expected<zypp::ManagedFile>> fetchKey ( 
const zypp::Url &url ) {
 
  125        return _reports.zyppContext()->provider ()->provide( url, zyppng::ProvideFileSpec() )
 
  126         | 
and_then( ProvideType::copyResultToDest( _reports.zyppContext()->provider(), _targetDirectory_r / zypp::Pathname( url.
getPathName() ).basename() ) );
 
  129      void importKeysInTargetDir () {
 
  130        MIL << 
"Check for " << _keyID_r << 
" at " << _targetDirectory_r << std::endl;
 
  134        _reports.info( zypp::str::Format(
_(
"Looking for gpg key ID %1% in cache %2%.") ) %  _keyIDStr %  _targetDirectory_r );
 
  137                                      [
this]( 
const zypp::Pathname & dir_r, 
const std::string & str_r ){
 
  141              zypp::PathInfo fileInfo ( dir_r/str_r );
 
  147                _tempKeyRing.multiKeyImport(dir_r/str_r, 
true);
 
  149            } 
catch (
const zypp::KeyRingException& e) {
 
  151              ERR << 
"Error importing cached key from file '"<<dir_r/str_r<<
"'."<<std::endl;
 
  157      zypp::Pathname writeKeysToTargetDir() {
 
  163        for ( 
const auto & key: _tempKeyRing.trustedPublicKeyData()) {
 
  164          MIL << 
"KEY ID in KEYRING: " << key.id() << std::endl;
 
  166          zypp::Pathname keyFile =  _targetDirectory_r/(zypp::str::Format(
"%1%.key") % key.rpmName()).
asString();
 
  168          std::ofstream fout( keyFile.
c_str(), std::ios_base::out | std::ios_base::trunc );
 
  173          _tempKeyRing.dumpTrustedPublicKey( key.id(), fout );
 
  177        if ( !_tempKeyRing.isKeyTrusted( _keyID_r) ) {
 
  178          return zypp::Pathname();
 
  181        zypp::PublicKeyData keyData( _tempKeyRing.trustedPublicKeyData(  _keyID_r ) );
 
  183          ERR << 
"Error when exporting key from temporary keychain." << std::endl;
 
  184          return zypp::Pathname();
 
  187        return  _targetDirectory_r/(zypp::str::Format(
"%1%.key") % keyData.rpmName()).
asString();
 
  190      JobReportHelper<ZyppContextRefType> _reports;
 
  191      const zypp::RepoInfo    _info;
 
  192      const std::string _keyID_r;
 
  193      const zypp::Pathname    _targetDirectory_r;
 
  194      const std::string _keyIDStr;
 
  196      zypp::filesystem::TmpDir _tmpKeyRingDir;
 
  197      zypp::KeyRing _tempKeyRing;
 
  201    struct AsyncRepoInfoProvideKey : 
public RepoInfoProvideKeyLogic<AsyncRepoInfoProvideKey, zyppng::AsyncOp<zypp::Pathname>>
 
  203      using RepoInfoProvideKeyLogic::RepoInfoProvideKeyLogic;
 
  206    struct SyncRepoInfoProvideKey : 
public RepoInfoProvideKeyLogic<SyncRepoInfoProvideKey, zyppng::SyncOp<zypp::Pathname>>
 
  208      using RepoInfoProvideKeyLogic::RepoInfoProvideKeyLogic;
 
static const ValueType month
static Date now()
Return the current time.
@ STRINGEND
Match at string end.
What is known about a repository.
std::string asString() const
Returns a default string representation of the Url object.
std::string getPathName(EEncoding eflag=zypp::url::E_DECODED) const
Returns the path name from the URL.
const char * c_str() const
String representation.
bool empty() const
Test for an empty path.
static expected success(ConsParams &&...params)
#define ZYPP_ENABLE_LOGIC_BASE(Executor, OpType)
int unlink(const Pathname &path)
Like 'unlink'.
int dirForEach(const Pathname &dir_r, const StrMatcher &matcher_r, function< bool(const Pathname &, const char *const)> fnc_r)
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
AutoDispose< const Pathname > ManagedFile
A Pathname plus associated cleanup code to be executed when path is no longer needed.
std::string asString(const Patch::Category &obj)
zypp::Pathname provideKey(SyncContextRef ctx, zypp::RepoInfo info, std::string keyID_r, zypp::Pathname targetDirectory_r)
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
ResultType and_then(const expected< T, E > &exp, Function &&f)
Container< Ret > transform(Container< Msg, CArgs... > &&val, Transformation &&transformation)
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
#define ZYPP_FWD_CURRENT_EXCPT()
Drops a logline and returns the current Exception as a std::exception_ptr.
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.