libzypp  17.30.0
FileChecker.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #include <iostream>
13 #include <zypp/base/Logger.h>
14 #include <zypp/FileChecker.h>
15 #include <zypp/ZYppFactory.h>
16 #include <zypp/Digest.h>
17 #include <zypp/KeyRing.h>
18 
19 using std::endl;
20 
21 #undef ZYPP_BASE_LOGGER_LOGGROUP
22 #define ZYPP_BASE_LOGGER_LOGGROUP "FileChecker"
23 
25 namespace zypp
26 {
27 
29  : _checksum(checksum)
30  {}
31 
32  void ChecksumFileChecker::operator()( const Pathname &file ) const
33  {
34  //MIL << "checking " << file << " file against checksum '" << _checksum << "'" << endl;
36 
37  if ( _checksum.empty() )
38  {
39  MIL << "File " << file << " has no checksum available." << std::endl;
40  if ( report->askUserToAcceptNoDigest(file) )
41  {
42  MIL << "User accepted " << file << " with no checksum." << std::endl;
43  return;
44  }
45  else
46  {
47  ZYPP_THROW( ExceptionType( file.basename() + " has no checksum" ) );
48  }
49  }
50  else
51  {
52  CheckSum real_checksum( _checksum.type(), filesystem::checksum( file, _checksum.type() ));
53  if ( (real_checksum != _checksum) )
54  {
55  // Remember askUserToAcceptWrongDigest decision for at most 12hrs in memory;
56  // Actually we just want to prevent asking the same question again when the
57  // previously downloaded file is retrieved from the disk cache.
58  static std::map<std::string,std::string> exceptions;
59  static Date exceptionsAge;
60  Date now( Date::now() );
61  if ( !exceptions.empty() && now-exceptionsAge > 12*Date::hour )
62  exceptions.clear();
63 
64  WAR << "File " << file << " has wrong checksum " << real_checksum << " (expected " << _checksum << ")" << endl;
65  if ( !exceptions.empty() && exceptions[real_checksum.checksum()] == _checksum.checksum() )
66  {
67  WAR << "User accepted " << file << " with WRONG CHECKSUM. (remembered)" << std::endl;
68  return;
69  }
70  else if ( report->askUserToAcceptWrongDigest( file, _checksum.checksum(), real_checksum.checksum() ) )
71  {
72  WAR << "User accepted " << file << " with WRONG CHECKSUM." << std::endl;
73  exceptions[real_checksum.checksum()] = _checksum.checksum();
74  exceptionsAge = now;
75  return;
76  }
77  else
78  {
79  ZYPP_THROW( ExceptionType( file.basename() + " has wrong checksum" ) );
80  }
81  }
82  }
83  }
84 
85  void NullFileChecker::operator()(const Pathname &file ) const
86  {
87  MIL << "+ null check on " << file << endl;
88  return;
89  }
90 
91  void CompositeFileChecker::operator()(const Pathname &file ) const
92  {
93  //MIL << _checkers.size() << " checkers" << endl;
94  for ( std::list<FileChecker>::const_iterator it = _checkers.begin(); it != _checkers.end(); ++it )
95  {
96  if ( *it )
97  {
98  //MIL << "+ chk" << endl;
99  (*it)(file);
100  }
101  else
102  {
103  ERR << "Invalid checker" << endl;
104  }
105  }
106  }
107 
108  void CompositeFileChecker::add( const FileChecker &checker )
109  { _checkers.push_back(checker); }
110 
111 
113  {}
114 
116  { signature( std::move(signature_r) ); }
117 
118  void SignatureFileChecker::addPublicKey( const Pathname & publickey_r )
119  { addPublicKey( PublicKey(publickey_r) ); }
120 
121  void SignatureFileChecker::addPublicKey( const PublicKey & publickey_r )
122  { getZYpp()->keyRing()->importKey( publickey_r, false ); }
123 
124  void SignatureFileChecker::operator()( const Pathname & file_r ) const
125  {
126  const Pathname & sig { signature() };
127  if ( not ( sig.empty() || PathInfo(sig).isExist() ) )
128  ZYPP_THROW( ExceptionType("Signature " + sig.asString() + " not found.") );
129 
130  MIL << "Checking " << file_r << " file validity using digital signature.." << endl;
131  // const_cast because the workflow is allowed to store result values here
132  SignatureFileChecker & self { const_cast<SignatureFileChecker&>(*this) };
133  self.file( file_r );
134  if ( not getZYpp()->keyRing()->verifyFileSignatureWorkflow( self ) )
135  ZYPP_THROW( ExceptionType( "Signature verification failed for " + file_r.basename() ) );
136  }
137 
138  /******************************************************************
139  **
140  ** FUNCTION NAME : operator<<
141  ** FUNCTION TYPE : std::ostream &
142  */
143  std::ostream & operator<<( std::ostream & str, const FileChecker & obj )
144  {
145  return str;
146  }
147 
149 } // namespace zypp
bool empty() const
Definition: CheckSum.cc:173
std::string type() const
Definition: CheckSum.cc:167
std::string checksum() const
Definition: CheckSum.cc:170
void operator()(const Pathname &file) const
Try to validate the file.
Definition: FileChecker.cc:32
ChecksumFileChecker(const CheckSum &checksum)
Constructor.
Definition: FileChecker.cc:28
CheckSumCheckException ExceptionType
Definition: FileChecker.h:73
std::list< FileChecker > _checkers
Definition: FileChecker.h:163
void add(const FileChecker &checker)
Definition: FileChecker.cc:108
void operator()(const Pathname &file) const
Definition: FileChecker.cc:91
Store and operate on date (time_t).
Definition: Date.h:33
static const ValueType hour
Definition: Date.h:43
static Date now()
Return the current time.
Definition: Date.h:78
void operator()(const Pathname &file) const
Definition: FileChecker.cc:85
Class representing one GPG Public Key (PublicKeyData + ASCII armored in a tempfile).
Definition: PublicKey.h:359
Checks for the validity of a signature.
Definition: FileChecker.h:94
void operator()(const Pathname &file_r) const
Call KeyRing::verifyFileSignatureWorkflow to verify the file.
Definition: FileChecker.cc:124
void addPublicKey(const PublicKey &publickey_r)
Add a public key to the list of known keys.
Definition: FileChecker.cc:121
SignatureCheckException ExceptionType
Definition: FileChecker.h:96
SignatureFileChecker()
Default Ctor for unsigned files.
Definition: FileChecker.cc:112
Wrapper class for ::stat/::lstat.
Definition: PathInfo.h:221
std::string basename() const
Return the last component of this path.
Definition: Pathname.h:128
const Pathname & file() const
File to verify.
const Pathname & signature() const
Detached signature or empty.
String related utilities and Regular expression matching.
std::string checksum(const Pathname &file, const std::string &algorithm)
Compute a files checksum.
Definition: PathInfo.cc:1051
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2
std::ostream & operator<<(std::ostream &str, const SerialNumber &obj)
Definition: SerialNumber.cc:52
function< void(const Pathname &file)> FileChecker
Functor signature used to check files.
Definition: FileChecker.h:28
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:418
#define MIL
Definition: Logger.h:96
#define ERR
Definition: Logger.h:98
#define WAR
Definition: Logger.h:97