21 #include <zypp-core/zyppng/pipelines/Expected> 23 #include <zypp/ng/Context> 24 #include <zypp/ng/UserRequest> 28 template <
class Executor,
class OpType>
47 using zyppng::operators::operator|;
48 using zyppng::expected;
71 ERR <<
"Key [" <<
_keyId <<
"] from cache: " << cacheDir <<
" is not valid" << std::endl;
75 MIL <<
"Key [" <<
_keyId <<
"] " << key.
name() <<
" loaded from cache" << std::endl;
79 if ( !
executor()->askUserToAcceptPackageKey( key, context ) ) {
83 MIL <<
"User wants to import key [" <<
_keyId <<
"] " << key.
name() <<
" from cache" << std::endl;
85 _context->keyRing()->importKey( key,
true );
104 ERR <<
"Not implemented yet" << std::endl;
115 return report->askUserToAcceptPackageKey ( key_r, keycontext_r );
135 template <
class Executor,
class OpType>
136 struct VerifyFileSignatureLogic :
public LogicBase<Executor, OpType>
149 struct FoundKeyData {
155 MaybeAsyncRef<FoundKeyData> findKey (
const std::string &
id ) {
157 using zyppng::operators::operator|;
164 if ( trustedKeyData )
166 MIL <<
"Key is trusted: " << trustedKeyData << std::endl;
171 if ( generalKeyData )
181 if ( trustedKeyData.fingerprint() == generalKeyData.fingerprint()
182 && trustedKeyData.created() < generalKeyData.created() )
184 MIL <<
"Key was updated. Saving new version into trusted keyring: " << generalKeyData << std::endl;
186 trustedKeyData =
_keyRing->pimpl().publicKeyExists(
id,
_keyRing->pimpl().trustedKeyRing() );
195 if ( generalKeyData )
198 MIL <<
"Key [" <<
id <<
"] " << key.name() <<
" is not trusted" << std::endl;
207 MIL <<
"User wants to trust key [" <<
id <<
"] " << key.name() << std::endl;
211 MIL <<
"User wants to import key [" <<
id <<
"] " << key.name() << std::endl;
213 whichKeyring =
_keyRing->pimpl().trustedKeyRing();
216 whichKeyring =
_keyRing->pimpl().generalKeyRing();
218 return makeReadyResult(FoundKeyData { std::move(generalKeyData), std::move(whichKeyring),
true });
222 MIL <<
"User does not want to trust key [" <<
id <<
"] " << key.name() << std::endl;
230 | [
this,
id](
bool success ) {
234 return FoundKeyData{
_keyRing->pimpl().publicKeyExists(
id,
_keyRing->pimpl().trustedKeyRing() ),
_keyRing->pimpl().trustedKeyRing(),
true };
249 MIL <<
"Going to verify signature for " << filedesc <<
" ( " << file <<
" ) with " << signature << std::endl;
255 MIL <<
"askUserToAcceptUnsignedFile: " << res << std::endl;
264 std::list<zypp::PublicKeyData> buddies;
267 WAR <<
"buddy " << sid <<
": key id is too short to safely identify a gpg key. Skipping it." << std::endl;
270 if (
_keyRing->pimpl().trustedPublicKeyExists( sid ) ) {
271 MIL <<
"buddy " << sid <<
": already in trusted key ring. Not needed." << std::endl;
274 auto pk =
_keyRing->pimpl().publicKeyExists( sid );
276 WAR <<
"buddy " << sid <<
": not available in the public key ring. Skipping it." << std::endl;
279 if ( pk.providesKey(
id) ) {
280 MIL <<
"buddy " << sid <<
": is the signing key. Handled separately." << std::endl;
283 MIL <<
"buddy " << sid <<
": candidate for auto import. Remeber it." << std::endl;
284 buddies.push_back( pk );
287 using zyppng::operators::operator|;
288 return findKey(
id ) | [
this, id, buddies=std::move(buddies)]( FoundKeyData res ) {
295 if ( res._foundKey ) {
299 return makeReturn(
false);
303 executor()->infoVerify( filedesc, res._foundKey, keyContext );
304 if (
_keyRing->pimpl().verifyFile( file, signature, res._whichKeyRing ) )
309 MIL <<
"Validated with trusted key: importing buddy list..." << std::endl;
310 executor()->reportAutoImportKey( buddies, res._foundKey, keyContext );
311 for (
const auto & kd : buddies ) {
319 bool userAnswer =
executor()->askUserToAcceptVerificationFailed( filedesc,
_keyRing->pimpl().exportKey( res._foundKey, res._whichKeyRing ), keyContext );
320 MIL <<
"askUserToAcceptVerificationFailed: " << userAnswer << std::endl;
321 return makeReturn(userAnswer);
325 MIL <<
"File [" << file <<
"] ( " << filedesc <<
" ) signed with unknown key [" <<
id <<
"]" << std::endl;
327 MIL <<
"askUserToAcceptUnknownKey: " << res << std::endl;
328 return makeReturn(res);
331 return makeReturn(
false);
341 inline std::pair<bool, zypp::keyring::VerifyFileContext> makeReturn(
bool res ){
347 struct AsyncVerifyFileSignatureExecutor :
public VerifyFileSignatureLogic<AsyncVerifyFileSignatureExecutor, AsyncOp<std::pair<bool,zypp::keyring::VerifyFileContext>>>
350 using VerifyFileSignatureLogic::VerifyFileSignatureLogic;
352 bool askUserToAcceptUnsignedFile(
const std::string &file,
const zypp::KeyContext &keycontext = {} ) {
355 if (keycontext.empty())
358 _(
"File '%s' is unsigned, continue?")) % file;
362 _(
"File '%s' from repository '%s' is unsigned, continue?"))
363 % file % keycontext.repoInfo().asUserString();
368 return req->choice ();
373 auto req = TrustKeyRequest::create(
374 _(
"Do you want to reject the key, trust temporarily, or trust always?"),
379 return static_cast<KeyTrust
>(req->choice());
384 auto req = ShowMessageRequest::create( label, ShowMessageRequest::MType::Info,
VerifyInfoEvent::makeData ( file_r, keyData_r, keycontext) );
389 const std::string &lbl =
zypp::str::Format(
PL_(
"Received %1% new package signing key from repository \"%2%\":",
390 "Received %1% new package signing keys from repository \"%2%\":",
398 if ( keycontext.empty() )
400 label =
zypp::str::Format(
_(
"Signature verification failed for file '%1%'.") ) % file;
403 label =
zypp::str::Format(
_(
"Signature verification failed for file '%1%' from repository '%2%'.") ) % file % keycontext.repoInfo().asUserString();
406 label += std::string(
" ") +
_(
"Continue?");
409 return req->choice ();
412 bool askUserToAcceptUnknownKey(
const std::string &file,
const std::string &
id,
const zypp::KeyContext &keycontext = {} )
416 if (keycontext.empty())
419 _(
"File '%s' is signed with an unknown key '%s'. Continue?")) % file %
id;
423 _(
"File '%s' from repository '%s' is signed with an unknown key '%s'. Continue?"))
424 % file % keycontext.repoInfo().asUserString() % id;
428 return req->choice ();
432 struct SyncVerifyFileSignatureExecutor :
public VerifyFileSignatureLogic<SyncVerifyFileSignatureExecutor, SyncOp<std::pair<bool,zypp::keyring::VerifyFileContext>>>
435 using VerifyFileSignatureLogic::VerifyFileSignatureLogic;
437 bool askUserToAcceptUnsignedFile(
const std::string &file,
const zypp::KeyContext &keycontext = {} ) {
438 return _report->askUserToAcceptUnsignedFile( file, keycontext );
441 return _report->askUserToAcceptKey( key, keycontext );
444 return _report->infoVerify( file_r, keyData_r, keycontext );
447 return _report->reportAutoImportKey( keyDataList_r, keySigning_r, keyContext_r );
450 return _report->askUserToAcceptVerificationFailed( file, key, keycontext );
452 bool askUserToAcceptUnknownKey(
const std::string &file,
const std::string &
id,
const zypp::KeyContext &keycontext = {} ) {
453 return _report->askUserToAcceptUnknownKey( file,
id, keycontext );
463 auto kr = zyppContext->keyRing();
464 return SyncVerifyFileSignatureExecutor::run( std::move(zyppContext), std::move(kr), std::move(context_r) );
469 auto kr = zyppContext->keyRing();
470 return AsyncVerifyFileSignatureExecutor::run( std::move(zyppContext), std::move(kr), std::move(context_r) );
475 return SyncVerifyFileSignatureExecutor::run( std::move(zyppContext), std::move(keyRing), std::move(context_r) );
480 return AsyncVerifyFileSignatureExecutor::run( std::move(zyppContext), std::move(keyRing), std::move(context_r) );
bool fileValidated() const
Whether the signature was actually successfully verified.
static bool isSafeKeyId(const std::string &id_r)
Whether this is a long id (64bit/16byte) or even better a fingerprint.
bool askUserToAcceptPackageKey(const zypp::PublicKey &key_r, const zypp::KeyContext &keycontext_r=zypp::KeyContext())
ZyppContextRefType _context
zypp::PublicKeyData _foundKey
UserData makeData(const std::list< zypp::PublicKeyData > &keyDataList_r, const zypp::PublicKeyData &keySigning_r, const zypp::KeyContext &keyContext_r)
const std::string & signatureId() const
The id of the gpg key which signed the file.
zypp::keyring::VerifyFileContext _verifyContext
This basically means, we knew the key, but it was not trusted.
Class representing one GPG Public Keys data.
Pathname pubkeyCachePath() const
Path where the pubkey caches.
UserData makeData(const std::string &file, const zypp::PublicKey &key, const zypp::KeyContext &keycontext=zypp::KeyContext())
UserData makeData(const std::string &file_r, const zypp::PublicKeyData &keyData_r, const zypp::KeyContext &keycontext=zypp::KeyContext())
auto makeReadyResult(T &&res)
zypp::Pathname _whichKeyRing
std::string name() const
Key name.
bool provideAndImportKeyFromRepository(SyncContextRef ctx, std::string id_r, zypp::RepoInfo info_r)
Try to find the id in key cache or repository specified in info.
What is known about a repository.
I/O context for KeyRing::verifyFileSignatureWorkflow.
std::string asUserString() const
User string: label (alias or name)
typename ProvideType::Res ProvideRes
UserData makeData(const std::string &file, const std::string &id, const zypp::KeyContext &keycontext=zypp::KeyContext())
std::pair< bool, zypp::keyring::VerifyFileContext > verifyFileSignature(SyncContextRef zyppContext, zypp::keyring::VerifyFileContext &&context_r)
Follows a signature verification interacting with the user.
zypp::KeyRing_Ptr KeyRingRef
const KeyContext & keyContext() const
KeyContext passed to callbacks
bool signatureIdTrusted() const
Whether the SignatureId is in the trusted keyring (not temp.
void resetResults()
Reset all result values to safe defaults.
Pathname repoManagerRoot() const
The RepoManager root directory.
KeyTrust
User reply options for the askUserToTrustKey callback.
static std::enable_if_t< detail::is_async_op_v< FOpType >, AsyncOpRef< Result > > run(Args &&...args)
const Pathname & signature() const
Detached signature or empty.
bool isExist() const
Return whether valid stat info exists.
User has chosen not to trust the key.
Interim helper class to collect global options and settings.
ImportKeyFromRepoLogic(ZyppContextRefType context, std::string &&keyId, zypp::RepoInfo &&info)
std::conditional_t< detail::is_async_op_v< zyppng::AsyncOp< bool > >, AsyncOpRef< Type >, Type > MaybeAsyncRef
typename ProvideType::MediaHandle MediaHandle
const Pathname & file() const
File to verify.
const BuddyKeys & buddyKeys() const
UserData makeData(const zypp::PublicKey &key, const zypp::KeyContext &keycontext=zypp::KeyContext())
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
const RepoInfo repoInfo() const
bool askUserToAcceptPackageKey(const zypp::PublicKey &key_r, const zypp::KeyContext &keycontext_r=zypp::KeyContext())
Class representing one GPG Public Key (PublicKeyData + ASCII armored in a tempfile).
typename ZyppContextType::ProvideType ProvideType
Base class for Exception.
bool empty() const
Is the context unknown?
zypp::Pathname provideKey(SyncContextRef ctx, zypp::RepoInfo info, std::string keyID_r, zypp::Pathname targetDirectory_r)
#define PL_(MSG1, MSG2, N)
remove_smart_ptr_t< ZyppContextRefType > ZyppContextType
Wrapper class for ::stat/::lstat.
MaybeAsyncContextRef< OpType > ZyppContextRefType
bool fileAccepted() const
May return true due to user interaction or global defaults even if the signature was not actually ver...
zypp::callback::SendReport< zypp::KeyRingReport > _report
std::conditional_t< detail::is_async_op_v< OpType >, ContextRef, SyncContextRef > MaybeAsyncContextRef
ZYPP_ENABLE_LOGIC_BASE(Executor, OpType)
void setRepoInfo(const RepoInfo &repoinfo)
ZyppContextRefType _zyppContext
std::string shortFile() const
Short name for file (default: basename).
UserData makeData(const std::string &file, const zypp::KeyContext &keycontext=zypp::KeyContext())
MaybeAsyncRef< bool > execute()