libzypp
10.5.0
|
00001 /*---------------------------------------------------------------------\ 00002 | ____ _ __ __ ___ | 00003 | |__ / \ / / . \ . \ | 00004 | / / \ V /| _/ _/ | 00005 | / /__ | | | | | | | 00006 | /_____||_| |_| |_| | 00007 | | 00008 \---------------------------------------------------------------------*/ 00012 #include <iostream> 00013 #include <sstream> 00014 00015 #include "zypp/base/Logger.h" 00016 #include "zypp/base/Gettext.h" 00017 #include "zypp/base/String.h" 00018 00019 #include "zypp/CheckSum.h" 00020 #include "zypp/Digest.h" 00021 00022 using std::endl; 00023 00025 namespace zypp 00026 { 00027 00028 const std::string & CheckSum::md5Type() 00029 { static std::string _type( "md5" ); return _type; } 00030 00031 const std::string & CheckSum::shaType() 00032 { static std::string _type( "sha" ); return _type; } 00033 00034 const std::string & CheckSum::sha1Type() 00035 { static std::string _type( "sha1" ); return _type; } 00036 00037 const std::string & CheckSum::sha256Type() 00038 { static std::string _type( "sha256" ); return _type; } 00039 00040 00041 CheckSum::CheckSum() 00042 {} 00043 00044 CheckSum::CheckSum( const std::string & type, const std::string & checksum ) 00045 : _type( str::toLower( type ) ) 00046 , _checksum( checksum ) 00047 { 00048 switch ( checksum.size() ) 00049 { 00050 case 64: 00051 if ( _type == sha256Type() ) 00052 return; 00053 if ( _type.empty() || _type == shaType() ) 00054 { 00055 _type = sha256Type(); 00056 return; 00057 } 00058 // else: dubious 00059 break; 00060 00061 case 40: 00062 if ( _type == sha1Type() ) 00063 return; 00064 if ( _type.empty() || _type == shaType() ) 00065 { 00066 _type = sha1Type(); 00067 return; 00068 } 00069 // else: dubious 00070 break; 00071 00072 case 32: 00073 if ( _type == md5Type() ) 00074 return; 00075 if ( _type.empty() ) 00076 { 00077 _type = md5Type(); 00078 return; 00079 } 00080 // else: dubious 00081 break; 00082 00083 case 0: 00084 return; // empty checksum is ok 00085 break; 00086 00087 default: 00088 if ( _type.empty() ) 00089 { 00090 WAR << "Can't determine type of " << checksum.size() << " byte checksum '" << _checksum << "'" << endl; 00091 return; 00092 } 00093 // else: dubious 00094 break; 00095 } 00096 00097 // dubious: Throw on malformed known types, otherwise log a warning. 00098 std::string msg = str::form ( _("Dubious type '%s' for %u byte checksum '%s'"), 00099 _type.c_str(), checksum.size(), _checksum.c_str() ); 00100 if ( _type == md5Type() 00101 || _type == shaType() 00102 || _type == sha1Type() 00103 || _type == sha256Type() ) 00104 { 00105 ZYPP_THROW( CheckSumException( msg ) ); 00106 } 00107 else 00108 { 00109 WAR << msg << endl; 00110 } 00111 } 00112 00113 CheckSum::CheckSum( const std::string & type_r, std::istream & input_r ) 00114 { 00115 if ( input_r.good() && ! type_r.empty() ) 00116 { 00117 _type = str::toLower( type_r ); 00118 _checksum = Digest::digest( _type, input_r ); 00119 if ( ! input_r.eof() || _checksum.empty() ) 00120 { 00121 _type = _checksum = std::string(); 00122 } 00123 } 00124 } 00125 00126 std::string CheckSum::type() const 00127 { return _type; } 00128 00129 std::string CheckSum::checksum() const 00130 { return _checksum; } 00131 00132 bool CheckSum::empty() const 00133 { return (checksum().empty() || type().empty()); } 00134 00135 std::string CheckSum::asString() const 00136 { 00137 std::ostringstream str; 00138 str << *this; 00139 return str.str(); 00140 } 00141 00142 std::ostream & operator<<( std::ostream & str, const CheckSum & obj ) 00143 { 00144 if ( obj.checksum().empty() ) 00145 { 00146 return str << std::string("NoCheckSum"); 00147 } 00148 00149 return str << ( obj.type().empty() ? std::string("UNKNOWN") : obj.type() ) << '-' << obj.checksum(); 00150 } 00151 00153 bool operator==( const CheckSum & lhs, const CheckSum & rhs ) 00154 { return lhs.checksum() == rhs.checksum() && lhs.type() == rhs.type(); } 00155 00157 bool operator!=( const CheckSum & lhs, const CheckSum & rhs ) 00158 { return ! ( lhs == rhs ); } 00159 00161 } // namespace zypp