- Check that the signature exists before checking
[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     callback::SendReport<DigestReport> report;
33     CheckSum real_checksum( _checksum.type(), filesystem::checksum( file, _checksum.type() ));
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("No checksum available"));
46       }
47     }
48     else
49     {
50       if ( (real_checksum != _checksum) )
51       {
52         if ( report->askUserToAcceptWrongDigest( file, _checksum.checksum(), real_checksum.checksum() ) )
53         {
54           WAR << "User accepted " <<  file << " with WRONG CHECKSUM." << std::endl;
55           return;
56         }
57         else
58         {
59           ZYPP_THROW(FileCheckException("Wrong checksum"));
60         }
61       }
62     }
63   }
64
65   void NullFileChecker::operator()(const Pathname &file ) const
66   {
67     return;
68   }
69
70   void CompositeFileChecker::operator()(const Pathname &file ) const
71   {
72     MIL << _checkers.size() << " checkers" << endl;
73     for ( list<FileChecker>::const_iterator it = _checkers.begin(); it != _checkers.end(); ++it )
74     { 
75       MIL << "checking..." << endl;
76       (*it)(file);
77     }
78   }
79   
80   void CompositeFileChecker::add( const FileChecker &checker )
81   {
82     //MIL << "||# " << _checkers.size() << endl;
83     _checkers.push_back(checker);
84     //MIL << "||* " << _checkers.size() << endl;
85     
86   }
87
88   SignatureFileChecker::SignatureFileChecker( const Pathname &signature )
89     : _signature(signature)
90   {
91   }
92   
93   SignatureFileChecker::SignatureFileChecker()
94   {
95   }
96   
97   void SignatureFileChecker::addPublicKey( const Pathname &publickey )
98   {
99     ZYpp::Ptr z = getZYpp();
100     z->keyRing()->importKey(publickey, false);
101   }
102   
103   void SignatureFileChecker::operator()(const Pathname &file ) const
104   {
105     ZYpp::Ptr z = getZYpp();
106
107     if ( ! PathInfo(_signature).isExist())
108     {
109       ZYPP_THROW(FileCheckException("Signature " + _signature.asString() + " not found."));
110     }
111
112     MIL << "checking " << file << " file validity using digital signature.." << endl;
113     bool valid = z->keyRing()->verifyFileSignatureWorkflow( file, string(), _signature);
114     if (!valid)
115       ZYPP_THROW(FileCheckException("Signature verification failed"));
116   }
117
118   /******************************************************************
119   **
120   **    FUNCTION NAME : operator<<
121   **    FUNCTION TYPE : std::ostream &
122   */
123   std::ostream & operator<<( std::ostream & str, const FileChecker & obj )
124   {
125     return str;
126   }
127
128   /////////////////////////////////////////////////////////////////
129 } // namespace zypp
130 ///////////////////////////////////////////////////////////////////