libzypp  17.8.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 namespace std;
20 
21 #undef ZYPP_BASE_LOGGER_LOGGROUP
22 #define ZYPP_BASE_LOGGER_LOGGROUP "FileChecker"
23 
25 namespace zypp
26 {
27 
28  ChecksumFileChecker::ChecksumFileChecker( const CheckSum &checksum )
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 ( 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  : _signature(signature)
114  {}
115 
117  {}
118 
120  { _context = keycontext; }
121 
122  void SignatureFileChecker::addPublicKey( const Pathname & publickey, const KeyContext & keycontext )
123  { addPublicKey( PublicKey(publickey), keycontext ); }
124 
125  void SignatureFileChecker::addPublicKey( const PublicKey & publickey, const KeyContext & keycontext )
126  {
127  getZYpp()->keyRing()->importKey(publickey, false);
128  _context = keycontext;
129  }
130 
132  {
133  if ( (! PathInfo(_signature).isExist()) && (!_signature.empty()) )
134  {
135  ZYPP_THROW( ExceptionType("Signature " + _signature.asString() + " not found.") );
136  }
137 
138  MIL << "checking " << file << " file validity using digital signature.." << endl;
139  _fileValidated = false;
140  _fileAccepted = getZYpp()->keyRing()->verifyFileSignatureWorkflow( file, file.basename(), _signature, _fileValidated, _context );
141 
142  if ( !_fileAccepted )
143  ZYPP_THROW( ExceptionType( "Signature verification failed for " + file.basename() ) );
144  }
145 
146  /******************************************************************
147  **
148  ** FUNCTION NAME : operator<<
149  ** FUNCTION TYPE : std::ostream &
150  */
151  std::ostream & operator<<( std::ostream & str, const FileChecker & obj )
152  {
153  return str;
154  }
155 
157 } // namespace zypp
void operator()(const Pathname &file) const
Definition: FileChecker.cc:85
#define MIL
Definition: Logger.h:79
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:392
std::string checksum() const
Definition: CheckSum.cc:170
String related utilities and Regular expression matching.
SignatureFileChecker()
Default Constructor.
Definition: FileChecker.cc:116
Definition: Arch.h:344
std::list< FileChecker > _checkers
Definition: FileChecker.h:203
std::string basename() const
Return the last component of this path.
Definition: Pathname.h:127
#define ERR
Definition: Logger.h:81
void addPublicKey(const PublicKey &publickey, const KeyContext &keycontext=KeyContext())
add a public key to the list of known keys
Definition: FileChecker.cc:125
DefaultIntegral< bool, false > _fileAccepted
Definition: FileChecker.h:164
void operator()(const Pathname &file) const
Try to validate the file.
Definition: FileChecker.cc:32
bool empty() const
Test for an empty path.
Definition: Pathname.h:113
Store and operate on date (time_t).
Definition: Date.h:32
std::ostream & operator<<(std::ostream &str, const Exception &obj)
Definition: Exception.cc:147
void operator()(const Pathname &file) const
Definition: FileChecker.cc:91
const std::string & asString() const
String representation.
Definition: Pathname.h:90
void add(const FileChecker &checker)
Definition: FileChecker.cc:108
#define WAR
Definition: Logger.h:80
DefaultIntegral< bool, false > _fileValidated
Definition: FileChecker.h:165
void operator()(const Pathname &file) const
Calls KeyRing::verifyFileSignatureWorkflow to verify the file.
Definition: FileChecker.cc:131
std::string type() const
Definition: CheckSum.cc:167
SignatureCheckException ExceptionType
Definition: FileChecker.h:96
static const ValueType hour
Definition: Date.h:43
Class representing one GPG Public Key (PublicKeyData + ASCII armored in a tempfile).
Definition: PublicKey.h:272
bool empty() const
Definition: CheckSum.cc:173
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:1004
callback::SendReport< DownloadProgressReport > * report
Definition: MediaCurl.cc:203
Wrapper class for ::stat/::lstat.
Definition: PathInfo.h:220
function< void(const Pathname &file)> FileChecker
Functor signature used to check files.
Definition: FileChecker.h:28
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:1
CheckSumCheckException ExceptionType
Definition: FileChecker.h:73
void setKeyContext(const KeyContext &keycontext)
Set context for this checker.
Definition: FileChecker.cc:119