libzypp 9.41.1
|
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 & checksum ) 00045 { 00046 *this = CheckSum( std::string(), checksum ); 00047 } 00048 00049 CheckSum::CheckSum( const std::string & type, const std::string & checksum ) 00050 : _type( str::toLower( type ) ) 00051 , _checksum( checksum ) 00052 { 00053 switch ( checksum.size() ) 00054 { 00055 case 64: 00056 if ( _type == sha256Type() ) 00057 return; 00058 if ( _type.empty() || _type == shaType() ) 00059 { 00060 _type = sha256Type(); 00061 return; 00062 } 00063 // else: dubious 00064 break; 00065 00066 case 40: 00067 if ( _type == sha1Type() ) 00068 return; 00069 if ( _type.empty() || _type == shaType() ) 00070 { 00071 _type = sha1Type(); 00072 return; 00073 } 00074 // else: dubious 00075 break; 00076 00077 case 32: 00078 if ( _type == md5Type() ) 00079 return; 00080 if ( _type.empty() ) 00081 { 00082 _type = md5Type(); 00083 return; 00084 } 00085 // else: dubious 00086 break; 00087 00088 case 0: 00089 return; // empty checksum is ok 00090 break; 00091 00092 default: 00093 if ( _type.empty() ) 00094 { 00095 WAR << "Can't determine type of " << checksum.size() << " byte checksum '" << _checksum << "'" << endl; 00096 return; 00097 } 00098 // else: dubious 00099 break; 00100 } 00101 00102 // dubious: Throw on malformed known types, otherwise log a warning. 00103 std::string msg = str::form ( _("Dubious type '%s' for %u byte checksum '%s'"), 00104 _type.c_str(), checksum.size(), _checksum.c_str() ); 00105 if ( _type == md5Type() 00106 || _type == shaType() 00107 || _type == sha1Type() 00108 || _type == sha256Type() ) 00109 { 00110 ZYPP_THROW( CheckSumException( msg ) ); 00111 } 00112 else 00113 { 00114 WAR << msg << endl; 00115 } 00116 } 00117 00118 CheckSum::CheckSum( const std::string & type_r, std::istream & input_r ) 00119 { 00120 if ( input_r.good() && ! type_r.empty() ) 00121 { 00122 _type = str::toLower( type_r ); 00123 _checksum = Digest::digest( _type, input_r ); 00124 if ( ! input_r.eof() || _checksum.empty() ) 00125 { 00126 _type = _checksum = std::string(); 00127 } 00128 } 00129 } 00130 00131 std::string CheckSum::type() const 00132 { return _type; } 00133 00134 std::string CheckSum::checksum() const 00135 { return _checksum; } 00136 00137 bool CheckSum::empty() const 00138 { return (checksum().empty() || type().empty()); } 00139 00140 std::string CheckSum::asString() const 00141 { 00142 std::ostringstream str; 00143 str << *this; 00144 return str.str(); 00145 } 00146 00147 std::ostream & operator<<( std::ostream & str, const CheckSum & obj ) 00148 { 00149 if ( obj.checksum().empty() ) 00150 { 00151 return str << std::string("NoCheckSum"); 00152 } 00153 00154 return str << ( obj.type().empty() ? std::string("UNKNOWN") : obj.type() ) << '-' << obj.checksum(); 00155 } 00156 00158 bool operator==( const CheckSum & lhs, const CheckSum & rhs ) 00159 { return lhs.checksum() == rhs.checksum() && lhs.type() == rhs.type(); } 00160 00162 bool operator!=( const CheckSum & lhs, const CheckSum & rhs ) 00163 { return ! ( lhs == rhs ); } 00164 00166 } // namespace zypp