17 #include <zypp-common/PublicKey.h> 21 #include <zypp-core/zyppng/pipelines/Expected> 23 #include <zypp/ng/Context> 25 #include <zypp/ng/UserRequest> 29 template <
class Executor,
class OpType>
48 using zyppng::operators::operator|;
71 if ( !res )
return false;
81 zypp::PublicKeyData keyData (
_context->keyRing()->publicKeyData(
_keyId) );
87 key = zypp::PublicKey(
_context->keyRing()->exportPublicKey( keyData ) );
93 if ( !key.isValid() ) {
94 ERR <<
"Key [" <<
_keyId <<
"] from known keyring is not valid" << std::endl;
98 MIL <<
"Key [" <<
_keyId <<
"] " << key.name() <<
" loaded from cache" << std::endl;
106 MIL <<
"User wants to import key [" <<
_keyId <<
"] " << key.name() <<
" from cache" << std::endl;
108 _context->keyRing()->importKey( key,
true );
109 }
catch (
const zypp::KeyRingException &e ) {
138 template <
class Executor,
class OpType>
139 struct VerifyFileSignatureLogic :
public LogicBase<Executor, OpType>
153 struct FoundKeyData {
159 MaybeAsyncRef<FoundKeyData> findKey (
const std::string &
id ) {
161 using zyppng::operators::operator|;
167 zypp::PublicKeyData trustedKeyData(
_keyRing->pimpl().publicKeyExists(
id,
_keyRing->pimpl().trustedKeyRing() ) );
168 if ( trustedKeyData )
170 MIL <<
"Key is trusted: " << trustedKeyData << std::endl;
174 zypp::PublicKeyData generalKeyData(
_keyRing->pimpl().publicKeyExists(
id,
_keyRing->pimpl().generalKeyRing() ) );
175 if ( generalKeyData )
185 if ( trustedKeyData.fingerprint() == generalKeyData.fingerprint()
186 && trustedKeyData.created() < generalKeyData.created() )
188 MIL <<
"Key was updated. Saving new version into trusted keyring: " << generalKeyData << std::endl;
190 trustedKeyData =
_keyRing->pimpl().publicKeyExists(
id,
_keyRing->pimpl().trustedKeyRing() );
198 zypp::PublicKeyData generalKeyData(
_keyRing->pimpl().publicKeyExists(
id,
_keyRing->pimpl().generalKeyRing() ) );
199 if ( generalKeyData )
201 zypp::PublicKey key(
_keyRing->pimpl().exportKey( generalKeyData,
_keyRing->pimpl().generalKeyRing() ) );
202 MIL <<
"Key [" <<
id <<
"] " << key.name() <<
" is not trusted" << std::endl;
211 MIL <<
"User wants to trust key [" <<
id <<
"] " << key.name() << std::endl;
215 MIL <<
"User wants to import key [" <<
id <<
"] " << key.name() << std::endl;
217 whichKeyring =
_keyRing->pimpl().trustedKeyRing();
220 whichKeyring =
_keyRing->pimpl().generalKeyRing();
222 return makeReadyResult(FoundKeyData { std::move(generalKeyData), std::move(whichKeyring),
true });
226 MIL <<
"User does not want to trust key [" <<
id <<
"] " << key.name() << std::endl;
234 | [
this,
id](
bool success ) {
238 return FoundKeyData{
_keyRing->pimpl().publicKeyExists(
id,
_keyRing->pimpl().trustedKeyRing() ),
_keyRing->pimpl().trustedKeyRing(),
true };
253 MIL <<
"Going to verify signature for " << filedesc <<
" ( " << file <<
" ) with " << signature << std::endl;
259 MIL <<
"askUserToAcceptUnsignedFile: " << res << std::endl;
267 MIL <<
"Failed to read the signature from " << signature << std::endl;
275 std::list<zypp::PublicKeyData> buddies;
277 if ( not zypp::PublicKeyData::isSafeKeyId( sid ) ) {
278 WAR <<
"buddy " << sid <<
": key id is too short to safely identify a gpg key. Skipping it." << std::endl;
281 if (
_keyRing->pimpl().trustedPublicKeyExists( sid ) ) {
282 MIL <<
"buddy " << sid <<
": already in trusted key ring. Not needed." << std::endl;
285 auto pk =
_keyRing->pimpl().publicKeyExists( sid );
287 WAR <<
"buddy " << sid <<
": not available in the public key ring. Skipping it." << std::endl;
290 if ( pk.providesKey(
id) ) {
291 MIL <<
"buddy " << sid <<
": is the signing key. Handled separately." << std::endl;
294 MIL <<
"buddy " << sid <<
": candidate for auto import. Remeber it." << std::endl;
295 buddies.push_back( pk );
298 using zyppng::operators::operator|;
299 return findKey(
id ) | [
this, id, buddies=std::move(buddies)]( FoundKeyData res ) {
306 if ( res._foundKey ) {
310 return makeReturn(
false);
315 if (
_keyRing->pimpl().verifyFile( file, signature, res._whichKeyRing ) )
320 MIL <<
"Validated with trusted key: importing buddy list..." << std::endl;
321 _keyringReport.reportAutoImportKey( buddies, res._foundKey, keyContext );
322 for (
const auto & kd : buddies ) {
330 bool userAnswer =
_keyringReport.askUserToAcceptVerificationFailed( filedesc,
_keyRing->pimpl().exportKey( res._foundKey, res._whichKeyRing ), keyContext );
331 MIL <<
"askUserToAcceptVerificationFailed: " << userAnswer << std::endl;
332 return makeReturn(userAnswer);
336 MIL <<
"File [" << file <<
"] ( " << filedesc <<
" ) signed with unknown key [" <<
id <<
"]" << std::endl;
338 MIL <<
"askUserToAcceptUnknownKey: " << res << std::endl;
339 return makeReturn(res);
342 return makeReturn(
false);
353 inline std::pair<bool, zypp::keyring::VerifyFileContext> makeReturn(
bool res ){
360 std::pair<bool,zypp::keyring::VerifyFileContext>
363 auto kr = zyppContext->keyRing();
369 auto kr = zyppContext->keyRing();
bool fileValidated() const
Whether the signature was actually successfully verified.
ZyppContextRefType _context
zypp::PublicKeyData _foundKey
bool importFromKnownKeyring()
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.
Pathname pubkeyCachePath() const
Path where the pubkey caches.
zypp::Pathname _whichKeyRing
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
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.
expected< void > fetchGpgKeys(SyncContextRef ctx, zypp::RepoInfo info)
Pathname repoManagerRoot() const
The RepoManager root directory.
bool info(std::string msg_r, UserData userData_r=UserData())
send message text
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 gpgKeyUrlsEmpty() const
Whether gpgkey URLs are defined.
bool isExist() const
Return whether valid stat info exists.
Interim helper class to collect global options and settings.
ImportKeyFromRepoLogic(ZyppContextRefType context, std::string &&keyId, zypp::RepoInfo &&info)
typename ProvideType::MediaHandle MediaHandle
const Pathname & file() const
File to verify.
KeyRingReportHelper< ZyppContextRefType > _keyringReport
const BuddyKeys & buddyKeys() const
auto makeReadyResult(T &&res)
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
const RepoInfo repoInfo() const
std::shared_ptr< AsyncOp< T > > AsyncOpRef
typename ZyppContextType::ProvideType ProvideType
Base class for Exception.
bool empty() const
Is the context unknown?
remove_smart_ptr_t< ZyppContextRefType > ZyppContextType
Wrapper class for ::stat/::lstat.
MaybeAsyncContextRef< OpType > ZyppContextRefType
std::conditional_t< isAsync, AsyncOpRef< Type >, Type > MaybeAsyncRef
bool fileAccepted() const
May return true due to user interaction or global defaults even if the signature was not actually ver...
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
typename remove_smart_ptr< T >::type remove_smart_ptr_t
std::string shortFile() const
Short name for file (default: basename).
MaybeAsyncRef< bool > execute()