libzypp 17.32.5
repoinfowf.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
9#include "repoinfowf.h"
16#include <zypp/KeyRing.h>
17#include <zypp/PublicKey.h>
18#include <zypp/ZYppCallbacks.h>
19
20#include <utility>
21#include <zypp-core/zyppng/pipelines/Transform>
22#include <zypp-core/zyppng/pipelines/Expected>
23#include <zypp-core/zyppng/pipelines/MTry>
24#include <zypp-media/ng/Provide>
25#include <zypp-media/ng/ProvideSpec>
26#include <zypp/MediaSetAccess.h>
27#include <zypp/ng/Context>
28#include <zypp/ng/UserRequest>
30
31#include <fstream>
32
33
34namespace zyppng {
35
36 namespace {
37
38 using namespace zyppng::operators;
39
40 template<class Executor, class OpType>
41 struct RepoInfoProvideKeyLogic : public LogicBase<Executor, OpType> {
42
43 using ZyppContextRefType = MaybeAsyncContextRef<OpType>;
44 using ZyppContextType = remove_smart_ptr_t<ZyppContextRefType>;
45 using ProvideType = typename ZyppContextType::ProvideType;
46 using MediaHandle = typename ProvideType::MediaHandle;
47 using ProvideRes = typename ProvideType::Res;
48
49 RepoInfoProvideKeyLogic( ZyppContextRefType &&zyppContext, zypp::RepoInfo &&info, std::string &&keyID_r, zypp::Pathname &&targetDirectory_r )
50 : _zyppContext( std::move(zyppContext) )
51 , _info( std::move(info) )
52 , _keyID_r(std::move( keyID_r ))
54 , _keyIDStr( _keyID_r.size() > 8 ? _keyID_r.substr( _keyID_r.size()-8 ) : _keyID_r ) // print short ID in Jobreports
56 { }
57
59
61 using namespace zyppng::operators;
62 using zyppng::operators::operator|;
63 using zyppng::expected;
64
65
66 if ( _keyID_r.empty() )
68
70
71 if ( _tempKeyRing.isKeyTrusted( _keyID_r) ) {
73 }
74
75 if ( _info.gpgKeyUrlsEmpty() ) {
76 // translator: %1% is a repositories name
77 executor()->info( zypp::str::Format(_("Repository %1% does not define additional 'gpgkey=' URLs.") ) % _info.asUserString() );
79 }
80
81 // no key in the cache is what we are looking for, lets download
82 // all keys specified in gpgkey= entries
83
84 // translator: %1% is a gpg key ID like 3DBDC284
85 // %2% is a repositories name
86 executor()->info( zypp::str::Format(_("Looking for gpg key ID %1% in repository %2%.") ) % _keyIDStr % _info.asUserString() );
87
88 return _info.gpgKeyUrls()
89 | transform( [this]( const zypp::Url &url ) {
90
91 executor()->info( " gpgkey=" + url.asString() );
92 return fetchKey( url )
93 | and_then( [this, url]( zypp::ManagedFile f ) -> expected<void> {
94 try {
95 if ( f->empty() )
96 return expected<void>::error(std::make_exception_ptr( zypp::Exception("Empty ManagedFile returned.") ));
97
98 zypp::PublicKey key(f);
99 if ( !key.isValid() )
100 return expected<void>::error(std::make_exception_ptr( zypp::Exception("Invalid public key.") ));
101
102 // import all keys into our temporary keyring
104
105 } catch ( const std::exception & e ) {
106 //ignore and continue to next url
107 ZYPP_CAUGHT(e);
108 MIL << "Key import from url:'"<<url<<"' failed." << std::endl;
109 return expected<void>::error( std::current_exception() );
110 }
111
113 });
114
115 })
116 | [this]( std::list<expected<void>> && ) ->zypp::Pathname {
117 return writeKeysToTargetDir();
118 };
119 }
120
121 protected:
122
124 return _zyppContext->provider ()->provide( url, zyppng::ProvideFileSpec() )
125 | and_then( ProvideType::copyResultToDest( _zyppContext->provider(), _targetDirectory_r / zypp::Pathname( url.getPathName() ).basename() ) );
126 }
127
128 void importKeysInTargetDir () {
129 MIL << "Check for " << _keyID_r << " at " << _targetDirectory_r << std::endl;
130
131 // translator: %1% is a gpg key ID like 3DBDC284
132 // %2% is a cache directories path
133 executor()->info( zypp::str::Format(_("Looking for gpg key ID %1% in cache %2%.") ) % _keyIDStr % _targetDirectory_r );
134 zypp::filesystem::dirForEach( _targetDirectory_r,
136 [this]( const zypp::Pathname & dir_r, const std::string & str_r ){
137 try {
138
139 // deprecate a month old keys
141 if ( zypp::Date::now() - fileInfo.mtime() > zypp::Date::month ) {
142 //if unlink fails, the file will be overriden in the next step, no need
143 //to show a error
145 } else {
147 }
148 } catch (const zypp::KeyRingException& e) {
149 ZYPP_CAUGHT(e);
150 ERR << "Error importing cached key from file '"<<dir_r/str_r<<"'."<<std::endl;
151 }
152 return true;
153 });
154 }
155
157
158 zypp::filesystem::assert_dir( _targetDirectory_r );
159
160 //now write all keys into their own files in cache, override existing ones to always have
161 //up to date key data
162 for ( const auto & key: _tempKeyRing.trustedPublicKeyData()) {
163 MIL << "KEY ID in KEYRING: " << key.id() << std::endl;
164
165 zypp::Pathname keyFile = _targetDirectory_r/(zypp::str::Format("%1%.key") % key.rpmName()).asString();
166
167 std::ofstream fout( keyFile.c_str(), std::ios_base::out | std::ios_base::trunc );
168
169 if (!fout)
170 ZYPP_THROW(zypp::Exception(zypp::str::form("Cannot open file %s",keyFile.c_str())));
171
173 }
174
175 // key is STILL not known, we give up
176 if ( !_tempKeyRing.isKeyTrusted( _keyID_r) ) {
177 return zypp::Pathname();
178 }
179
181 if ( !keyData ) {
182 ERR << "Error when exporting key from temporary keychain." << std::endl;
183 return zypp::Pathname();
184 }
185
186 return _targetDirectory_r/(zypp::str::Format("%1%.key") % keyData.rpmName()).asString();
187 }
188
189 ZyppContextRefType _zyppContext;
191 const std::string _keyID_r;
193 const std::string _keyIDStr;
194
197 };
198
199
200 struct AsyncRepoInfoProvideKey : public RepoInfoProvideKeyLogic<AsyncRepoInfoProvideKey, zyppng::AsyncOp<zypp::Pathname>>
201 {
202 using RepoInfoProvideKeyLogic::RepoInfoProvideKeyLogic;
203 bool info( const std::string & msg_r, const UserData & userData_r = UserData() ) {
204 _zyppContext->sendUserRequest( ShowMessageRequest::create( msg_r, ShowMessageRequest::MType::Info, userData_r ) );
205 return true;
206 }
207 };
208
209 struct SyncRepoInfoProvideKey : public RepoInfoProvideKeyLogic<SyncRepoInfoProvideKey, zyppng::SyncOp<zypp::Pathname>>
210 {
211 using RepoInfoProvideKeyLogic::RepoInfoProvideKeyLogic;
212 bool info( const std::string & msg_r, const UserData & userData_r = UserData() ) {
214 }
215 };
216 }
217
219 {
220 return SyncRepoInfoProvideKey::run( std::move(ctx), std::move(info), std::move(keyID_r), std::move(targetDirectory_r) );
221 }
222
224 {
225 return AsyncRepoInfoProvideKey::run( std::move(ctx), std::move(info), std::move(keyID_r), std::move(targetDirectory_r) );
226 }
227
228}
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
Definition AutoDispose.h:95
static const ValueType month
Definition Date.h:49
static Date now()
Return the current time.
Definition Date.h:78
Base class for Exception.
Definition Exception.h:147
Gpg key handling.
Definition KeyRing.h:187
void dumpTrustedPublicKey(const std::string &id, std::ostream &stream)
Definition KeyRing.h:237
void multiKeyImport(const Pathname &keyfile_r, bool trusted_r=false)
Initial import from RpmDb.
Definition KeyRing.cc:465
std::list< PublicKeyData > trustedPublicKeyData()
Get a list of trusted public key data in the keyring (key data only)
Definition KeyRing.cc:483
bool isKeyTrusted(const std::string &id)
true if the key id is trusted
Definition KeyRing.cc:506
@ STRINGEND
Match at string end.
Definition StrMatcher.h:45
Class representing one GPG Public Keys data.
Definition PublicKey.h:208
Class representing one GPG Public Key (PublicKeyData + ASCII armored in a tempfile).
Definition PublicKey.h:365
What is known about a repository.
Definition RepoInfo.h:72
url_set gpgKeyUrls() const
The list of gpgkey URLs defined for this repo.
Definition RepoInfo.cc:617
bool gpgKeyUrlsEmpty() const
Whether gpgkey URLs are defined.
Definition RepoInfo.cc:611
String matching (STRING|SUBSTRING|GLOB|REGEX).
Definition StrMatcher.h:298
Url manipulation class.
Definition Url.h:92
std::string asString() const
Returns a default string representation of the Url object.
Definition Url.cc:501
std::string getPathName(EEncoding eflag=zypp::url::E_DECODED) const
Returns the path name from the URL.
Definition Url.cc:608
Typesafe passing of user data via callbacks.
Definition UserData.h:39
Wrapper class for stat/lstat.
Definition PathInfo.h:222
const char * c_str() const
String representation.
Definition Pathname.h:110
std::string basename() const
Return the last component of this path.
Definition Pathname.h:128
Provide a new empty temporary directory and recursively delete it when no longer needed.
Definition TmpPath.h:182
std::string asUserString() const
User string: label (alias or name)
A ProvideRes object is a reference counted ownership of a resource in the cache provided by a Provide...
Definition provideres.h:36
static expected success(ConsParams &&...params)
Definition expected.h:115
#define ZYPP_ENABLE_LOGIC_BASE(Executor, OpType)
Definition Arch.h:364
int unlink(const Pathname &path)
Like 'unlink'.
Definition PathInfo.cc:701
int dirForEach(const Pathname &dir_r, const StrMatcher &matcher_r, function< bool(const Pathname &, const char *const)> fnc_r)
Definition PathInfo.cc:32
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
Definition PathInfo.cc:320
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
Definition String.cc:37
std::string asString(const Patch::Category &obj)
Definition Patch.cc:122
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)
Definition asyncop.h:297
ResultType and_then(const expected< T, E > &exp, Function &&f)
Definition expected.h:367
zypp::callback::UserData UserData
Definition userrequest.h:18
Container< Ret > transform(Container< Msg, CArgs... > &&val, Transformation &&transformation)
Definition transform.h:31
zypp::filesystem::TmpDir _tmpKeyRingDir
zypp::KeyRing _tempKeyRing
const zypp::Pathname _targetDirectory_r
const std::string _keyIDStr
const zypp::RepoInfo _info
const std::string _keyID_r
ZyppContextRefType _zyppContext
static bool info(const std::string &msg_r, const UserData &userData_r=UserData())
send message text
Convenient building of std::string with boost::format.
Definition String.h:253
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition Exception.h:437
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition Exception.h:429
#define _(MSG)
Definition Gettext.h:37
#define MIL
Definition Logger.h:96
#define ERR
Definition Logger.h:98