libzypp  17.35.16
checksumwf.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
9 
10 #include "checksumwf.h"
11 #include "logichelpers.h"
12 
13 #include <zypp-core/Date.h>
14 #include <zypp-core/Pathname.h>
15 #include <zypp-core/CheckSum.h>
16 #include <zypp-core/base/Gettext.h>
17 #include <zypp-core/fs/PathInfo.h>
18 #include <utility>
19 #include <zypp-core/zyppng/pipelines/Expected>
20 #include <zypp-media/FileCheckException>
21 #include <zypp-media/ng/Provide>
22 #include <zypp/Digest.h>
23 #include <zypp/ng/Context>
24 #include <zypp/ng/reporthelper.h>
25 #include <zypp/ng/UserRequest>
26 
27 #include <map>
28 
30 
31  using namespace zyppng::operators;
32 
33  template <class Executor, class OpType >
34  struct CheckSumWorkflowLogic : public LogicBase<Executor, OpType>
35  {
36  ZYPP_ENABLE_LOGIC_BASE(Executor, OpType);
37 
40  using ProvideType = typename ZyppContextType::ProvideType;
41  using MediaHandle = typename ProvideType::MediaHandle;
42  using ProvideRes = typename ProvideType::Res;
43 
45  : _context( std::move(zyppContext) )
46  , _report( _context )
47  , _checksum(std::move( checksum ))
48  , _file(std::move( file ))
49  {}
50 
51  auto execute()
52  {
53 
54  //MIL << "checking " << file << " file against checksum '" << _checksum << "'" << endl;
55  if ( _checksum.empty() ) {
56  MIL << "File " << _file << " has no checksum available." << std::endl;
57  if ( _report.askUserToAcceptNoDigest( _file ) ) {
58  MIL << "User accepted " << _file << " with no checksum." << std::endl;
60  } else {
62  }
63 
64  } else {
65 
66  return _context->provider()->checksumForFile ( _file, _checksum.type() )
67  | [] ( expected<zypp::CheckSum> sum ) {
68  if ( !sum )
69  return zypp::CheckSum( );
70  return sum.get();
71  }
72  | [this, _file=_file]( zypp::CheckSum real_checksum ){
73  if ( (real_checksum != _checksum) )
74  {
75  // Remember askUserToAcceptWrongDigest decision for at most 12hrs in memory;
76  // Actually we just want to prevent asking the same question again when the
77  // previously downloaded file is retrieved from the disk cache.
78  static std::map<std::string,std::string> exceptions;
79  static zypp::Date exceptionsAge;
80  zypp::Date now( zypp::Date::now() );
81  if ( !exceptions.empty() && now-exceptionsAge > 12*zypp::Date::hour )
82  exceptions.clear();
83 
84  WAR << "File " << _file << " has wrong checksum " << real_checksum << " (expected " << _checksum << ")" << std::endl;
85  if ( !exceptions.empty() && exceptions[real_checksum.checksum()] == _checksum.checksum() )
86  {
87  WAR << "User accepted " << _file << " with WRONG CHECKSUM. (remembered)" << std::endl;
88  return expected<void>::success();
89  }
90  else if ( _report.askUserToAcceptWrongDigest( _file, _checksum.checksum(), real_checksum.checksum() ) )
91  {
92  WAR << "User accepted " << _file << " with WRONG CHECKSUM." << std::endl;
93  exceptions[real_checksum.checksum()] = _checksum.checksum();
94  exceptionsAge = now;
95  return expected<void>::success();
96  }
97  else
98  {
99  return expected<void>::error( ZYPP_EXCPT_PTR(zypp::FileCheckException( _file.basename() + " has wrong checksum" ) ) );
100  }
101  }
102  return expected<void>::success();
103  };
104  }
105  }
106 
107  protected:
112 
113  };
114 
116  {
117  return SimpleExecutor<CheckSumWorkflowLogic, SyncOp<expected<void>>>::run( std::move(zyppCtx), std::move(checksum), std::move(file) );
118  }
119 
121  {
122  return SimpleExecutor<CheckSumWorkflowLogic, AsyncOp<expected<void>>>::run( std::move(zyppCtx), std::move(checksum), std::move(file) );
123  }
124 
125  std::function<AsyncOpRef<expected<ProvideRes> > (ProvideRes &&)> checksumFileChecker( ContextRef zyppCtx, zypp::CheckSum checksum )
126  {
127  using zyppng::operators::operator|;
128  return [ zyppCtx, checksum=std::move(checksum) ]( ProvideRes res ) mutable -> AsyncOpRef<expected<ProvideRes>> {
129  return verifyChecksum( zyppCtx, std::move(checksum), res.file() )
130  | [ res ] ( expected<void> result ) mutable {
131  if ( result )
132  return expected<ProvideRes>::success( std::move(res) );
133  else
134  return expected<ProvideRes>::error( std::move(result.error()) );
135  };
136  };
137  }
138 
139  std::function<expected<SyncProvideRes> (SyncProvideRes &&)> checksumFileChecker(SyncContextRef zyppCtx, zypp::CheckSum checksum)
140  {
141  using zyppng::operators::operator|;
142  return [ zyppCtx = std::move(zyppCtx), checksum=std::move(checksum) ]( SyncProvideRes res ) mutable -> expected<SyncProvideRes> {
143  return verifyChecksum( zyppCtx, std::move(checksum), res.file() )
144  | [ res ] ( expected<void> result ) mutable {
145  if ( result )
146  return expected<SyncProvideRes>::success( std::move(res) );
147  else
148  return expected<SyncProvideRes>::error( std::move(result.error()) );
149  };
150  };
151  }
152 
153 }
#define MIL
Definition: Logger.h:100
MaybeAsyncContextRef< OpType > ZyppContextRefType
Definition: checksumwf.cc:38
std::function< AsyncOpRef< expected< ProvideRes > >ProvideRes &&)> checksumFileChecker(ContextRef zyppCtx, zypp::CheckSum checksum)
Definition: checksumwf.cc:125
A ProvideRes object is a reference counted ownership of a resource in the cache provided by a Provide...
Definition: provideres.h:35
Definition: Arch.h:363
std::string basename() const
Return the last component of this path.
Definition: Pathname.h:130
static expected error(ConsParams &&...params)
Definition: expected.h:126
#define ZYPP_EXCPT_PTR(EXCPT)
Drops a logline and returns Exception as a std::exception_ptr.
Definition: Exception.h:428
Store and operate on date (time_t).
Definition: Date.h:32
typename ZyppContextType::ProvideType ProvideType
Definition: checksumwf.cc:40
#define WAR
Definition: Logger.h:101
#define ZYPP_ENABLE_LOGIC_BASE(Executor, OpType)
Definition: logichelpers.h:223
std::conditional_t< isAsync, AsyncOpRef< T >, T > makeReadyResult(T &&result)
Definition: asyncop.h:297
static expected success(ConsParams &&...params)
Definition: expected.h:115
static const ValueType hour
Definition: Date.h:43
std::shared_ptr< AsyncOp< T > > AsyncOpRef
Definition: asyncop.h:255
DigestReportHelper< ZyppContextRefType > _report
Definition: checksumwf.cc:109
static Date now()
Return the current time.
Definition: Date.h:78
std::string checksum(const Pathname &file, const std::string &algorithm)
Compute a files checksum.
Definition: PathInfo.cc:1056
expected< void > verifyChecksum(SyncContextRef zyppCtx, zypp::CheckSum checksum, zypp::Pathname file)
Definition: checksumwf.cc:115
typename ProvideType::MediaHandle MediaHandle
Definition: checksumwf.cc:41
std::conditional_t< detail::is_async_op_v< OpType >, ContextRef, SyncContextRef > MaybeAsyncContextRef
Definition: contextfacade.h:51
zypp::Pathname _file
Definition: downloadwf.cc:202
typename remove_smart_ptr< T >::type remove_smart_ptr_t
Definition: type_traits.h:128
CheckSumWorkflowLogic(ZyppContextRefType zyppContext, zypp::CheckSum &&checksum, zypp::Pathname file)
Definition: checksumwf.cc:44
remove_smart_ptr_t< ZyppContextRefType > ZyppContextType
Definition: checksumwf.cc:39