libzypp  10.5.0
FileChecker.cc
Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 #include <iostream>
00013 #include "zypp/base/Logger.h"
00014 #include "zypp/FileChecker.h"
00015 #include "zypp/ZYppFactory.h"
00016 #include "zypp/Digest.h"
00017 #include "zypp/KeyRing.h"
00018 
00019 using namespace std;
00020 
00022 namespace zypp
00023 { 
00024 
00025   ChecksumFileChecker::ChecksumFileChecker( const CheckSum &checksum )
00026     : _checksum(checksum)
00027   {
00028   }
00029 
00030   void ChecksumFileChecker::operator()( const Pathname &file ) const
00031   {
00032       //MIL << "checking " << file << " file against checksum '" << _checksum << "'" << endl;
00033     callback::SendReport<DigestReport> report;
00034 
00035     if ( _checksum.empty() )
00036     {
00037       MIL << "File " <<  file << " has no checksum available." << std::endl;
00038       if ( report->askUserToAcceptNoDigest(file) )
00039       {
00040         MIL << "User accepted " <<  file << " with no checksum." << std::endl;
00041         return;
00042       }
00043       else
00044       {
00045         ZYPP_THROW( FileCheckException( file.basename() + " has no checksum" ) );
00046       }
00047     }
00048     else
00049     {
00050       CheckSum real_checksum( _checksum.type(), filesystem::checksum( file, _checksum.type() ));
00051       if ( (real_checksum != _checksum) )
00052       {
00053         if ( report->askUserToAcceptWrongDigest( file, _checksum.checksum(), real_checksum.checksum() ) )
00054         {
00055           WAR << "User accepted " <<  file << " with WRONG CHECKSUM." << std::endl;
00056           return;
00057         }
00058         else
00059         {
00060           ZYPP_THROW( FileCheckException( file.basename() + " has wrong checksum" ) );
00061         }
00062       }
00063     }
00064   }
00065 
00066   void NullFileChecker::operator()(const Pathname &file ) const
00067   {
00068     MIL << "+ null check on " << file << endl;
00069     return;
00070   }
00071 
00072   void CompositeFileChecker::operator()(const Pathname &file ) const
00073   {
00074     //MIL << _checkers.size() << " checkers" << endl;
00075     for ( list<FileChecker>::const_iterator it = _checkers.begin(); it != _checkers.end(); ++it )
00076     {
00077       if ( *it )
00078       {
00079         //MIL << "+ chk" << endl;
00080         (*it)(file);
00081       }
00082       else
00083       {
00084         ERR << "Invalid checker" << endl;
00085       }
00086     }
00087   }
00088 
00089   void CompositeFileChecker::add( const FileChecker &checker )
00090   {
00091     //MIL << "||# " << _checkers.size() << endl;
00092     _checkers.push_back(checker);
00093     //MIL << "||* " << _checkers.size() << endl;
00094 
00095   }
00096 
00097    SignatureFileChecker::SignatureFileChecker( const Pathname &signature )
00098        : _signature(signature)
00099   {
00100 
00101   }
00102 
00103 
00104   SignatureFileChecker::SignatureFileChecker()
00105   {
00106   }
00107 
00108   void SignatureFileChecker::setKeyContext(const KeyContext & keycontext)
00109   { _context = keycontext; }
00110 
00111   void SignatureFileChecker::addPublicKey( const Pathname & publickey, const KeyContext & keycontext )
00112   { addPublicKey( PublicKey(publickey), keycontext ); }
00113 
00114   void SignatureFileChecker::addPublicKey( const PublicKey & publickey, const KeyContext & keycontext )
00115   {
00116     getZYpp()->keyRing()->importKey(publickey, false);
00117     _context = keycontext;
00118   }
00119 
00120   void SignatureFileChecker::operator()(const Pathname &file ) const
00121   {
00122     ZYpp::Ptr z = getZYpp();
00123 
00124     if ( (! PathInfo(_signature).isExist()) && (!_signature.empty()))
00125     {
00126       ZYPP_THROW(FileCheckException("Signature " + _signature.asString() + " not found."));
00127     }
00128 
00129     MIL << "checking " << file << " file validity using digital signature.." << endl;
00130     bool valid = z->keyRing()->verifyFileSignatureWorkflow( file, file.basename(), _signature, _context);
00131 
00132     if (!valid)
00133       ZYPP_THROW( FileCheckException( "Signature verification failed for "  + file.basename() ) );
00134   }
00135 
00136   /******************************************************************
00137   **
00138   **    FUNCTION NAME : operator<<
00139   **    FUNCTION TYPE : std::ostream &
00140   */
00141   std::ostream & operator<<( std::ostream & str, const FileChecker & obj )
00142   {
00143     return str;
00144   }
00145 
00147 } // namespace zypp