1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/FileChecker.cc
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>
21 #undef ZYPP_BASE_LOGGER_LOGGROUP
22 #define ZYPP_BASE_LOGGER_LOGGROUP "FileChecker"
24 ///////////////////////////////////////////////////////////////////
26 { /////////////////////////////////////////////////////////////////
28 ChecksumFileChecker::ChecksumFileChecker( const CheckSum &checksum )
32 void ChecksumFileChecker::operator()( const Pathname &file ) const
34 //MIL << "checking " << file << " file against checksum '" << _checksum << "'" << endl;
35 callback::SendReport<DigestReport> report;
37 if ( _checksum.empty() )
39 MIL << "File " << file << " has no checksum available." << std::endl;
40 if ( report->askUserToAcceptNoDigest(file) )
42 MIL << "User accepted " << file << " with no checksum." << std::endl;
47 ZYPP_THROW( ExceptionType( file.basename() + " has no checksum" ) );
52 CheckSum real_checksum( _checksum.type(), filesystem::checksum( file, _checksum.type() ));
53 if ( (real_checksum != _checksum) )
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 )
64 WAR << "File " << file << " has wrong checksum " << real_checksum << " (expected " << _checksum << ")" << endl;
65 if ( !exceptions.empty() && exceptions[real_checksum.checksum()] == _checksum.checksum() )
67 WAR << "User accepted " << file << " with WRONG CHECKSUM. (remembered)" << std::endl;
70 else if ( report->askUserToAcceptWrongDigest( file, _checksum.checksum(), real_checksum.checksum() ) )
72 WAR << "User accepted " << file << " with WRONG CHECKSUM." << std::endl;
73 exceptions[real_checksum.checksum()] = _checksum.checksum();
79 ZYPP_THROW( ExceptionType( file.basename() + " has wrong checksum" ) );
85 void NullFileChecker::operator()(const Pathname &file ) const
87 MIL << "+ null check on " << file << endl;
91 void CompositeFileChecker::operator()(const Pathname &file ) const
93 //MIL << _checkers.size() << " checkers" << endl;
94 for ( std::list<FileChecker>::const_iterator it = _checkers.begin(); it != _checkers.end(); ++it )
98 //MIL << "+ chk" << endl;
103 ERR << "Invalid checker" << endl;
108 void CompositeFileChecker::add( const FileChecker &checker )
109 { _checkers.push_back(checker); }
112 SignatureFileChecker::SignatureFileChecker( const Pathname & signature )
113 : _signature(signature)
116 SignatureFileChecker::SignatureFileChecker()
119 void SignatureFileChecker::setKeyContext(const KeyContext & keycontext)
120 { _context = keycontext; }
122 void SignatureFileChecker::addPublicKey( const Pathname & publickey, const KeyContext & keycontext )
123 { addPublicKey( PublicKey(publickey), keycontext ); }
125 void SignatureFileChecker::addPublicKey( const PublicKey & publickey, const KeyContext & keycontext )
127 getZYpp()->keyRing()->importKey(publickey, false);
128 _context = keycontext;
131 void SignatureFileChecker::operator()(const Pathname &file ) const
133 if ( (! PathInfo(_signature).isExist()) && (!_signature.empty()) )
135 ZYPP_THROW( ExceptionType("Signature " + _signature.asString() + " not found.") );
138 MIL << "checking " << file << " file validity using digital signature.." << endl;
139 _fileValidated = false;
140 _fileAccepted = getZYpp()->keyRing()->verifyFileSignatureWorkflow( file, file.basename(), _signature, _fileValidated, _context );
142 if ( !_fileAccepted )
143 ZYPP_THROW( ExceptionType( "Signature verification failed for " + file.basename() ) );
146 /******************************************************************
148 ** FUNCTION NAME : operator<<
149 ** FUNCTION TYPE : std::ostream &
151 std::ostream & operator<<( std::ostream & str, const FileChecker & obj )
156 /////////////////////////////////////////////////////////////////
158 ///////////////////////////////////////////////////////////////////