Imported Upstream version 15.0.0
[platform/upstream/libzypp.git] / zypp / FileChecker.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/FileChecker.cc
10  *
11 */
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 ///////////////////////////////////////////////////////////////////
22 namespace zypp
23 { /////////////////////////////////////////////////////////////////
24
25   ChecksumFileChecker::ChecksumFileChecker( const CheckSum &checksum )
26     : _checksum(checksum)
27   {
28   }
29
30   void ChecksumFileChecker::operator()( const Pathname &file ) const
31   {
32       //MIL << "checking " << file << " file against checksum '" << _checksum << "'" << endl;
33     callback::SendReport<DigestReport> report;
34
35     if ( _checksum.empty() )
36     {
37       MIL << "File " <<  file << " has no checksum available." << std::endl;
38       if ( report->askUserToAcceptNoDigest(file) )
39       {
40         MIL << "User accepted " <<  file << " with no checksum." << std::endl;
41         return;
42       }
43       else
44       {
45         ZYPP_THROW( FileCheckException( file.basename() + " has no checksum" ) );
46       }
47     }
48     else
49     {
50       CheckSum real_checksum( _checksum.type(), filesystem::checksum( file, _checksum.type() ));
51       if ( (real_checksum != _checksum) )
52       {
53         if ( report->askUserToAcceptWrongDigest( file, _checksum.checksum(), real_checksum.checksum() ) )
54         {
55           WAR << "User accepted " <<  file << " with WRONG CHECKSUM." << std::endl;
56           return;
57         }
58         else
59         {
60           ZYPP_THROW( FileCheckException( file.basename() + " has wrong checksum" ) );
61         }
62       }
63     }
64   }
65
66   void NullFileChecker::operator()(const Pathname &file ) const
67   {
68     MIL << "+ null check on " << file << endl;
69     return;
70   }
71
72   void CompositeFileChecker::operator()(const Pathname &file ) const
73   {
74     //MIL << _checkers.size() << " checkers" << endl;
75     for ( list<FileChecker>::const_iterator it = _checkers.begin(); it != _checkers.end(); ++it )
76     {
77       if ( *it )
78       {
79         //MIL << "+ chk" << endl;
80         (*it)(file);
81       }
82       else
83       {
84         ERR << "Invalid checker" << endl;
85       }
86     }
87   }
88
89   void CompositeFileChecker::add( const FileChecker &checker )
90   {
91     //MIL << "||# " << _checkers.size() << endl;
92     _checkers.push_back(checker);
93     //MIL << "||* " << _checkers.size() << endl;
94
95   }
96
97    SignatureFileChecker::SignatureFileChecker( const Pathname &signature )
98        : _signature(signature)
99   {
100
101   }
102
103
104   SignatureFileChecker::SignatureFileChecker()
105   {
106   }
107
108   void SignatureFileChecker::setKeyContext(const KeyContext & keycontext)
109   { _context = keycontext; }
110
111   void SignatureFileChecker::addPublicKey( const Pathname & publickey, const KeyContext & keycontext )
112   { addPublicKey( PublicKey(publickey), keycontext ); }
113
114   void SignatureFileChecker::addPublicKey( const PublicKey & publickey, const KeyContext & keycontext )
115   {
116     getZYpp()->keyRing()->importKey(publickey, false);
117     _context = keycontext;
118   }
119
120   void SignatureFileChecker::operator()(const Pathname &file ) const
121   {
122     ZYpp::Ptr z = getZYpp();
123
124     if ( (! PathInfo(_signature).isExist()) && (!_signature.empty()))
125     {
126       ZYPP_THROW(FileCheckException("Signature " + _signature.asString() + " not found."));
127     }
128
129     MIL << "checking " << file << " file validity using digital signature.." << endl;
130     bool valid = z->keyRing()->verifyFileSignatureWorkflow( file, file.basename(), _signature, _context);
131
132     if (!valid)
133       ZYPP_THROW( FileCheckException( "Signature verification failed for "  + file.basename() ) );
134   }
135
136   /******************************************************************
137   **
138   **    FUNCTION NAME : operator<<
139   **    FUNCTION TYPE : std::ostream &
140   */
141   std::ostream & operator<<( std::ostream & str, const FileChecker & obj )
142   {
143     return str;
144   }
145
146   /////////////////////////////////////////////////////////////////
147 } // namespace zypp
148 ///////////////////////////////////////////////////////////////////