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