| 1 | // -*- mode: cpp; mode: fold -*- |
| 2 | // Description /*{{{*/ |
| 3 | // $Id: hashes.h,v 1.2 2001/03/11 05:30:20 jgg Exp $ |
| 4 | /* ###################################################################### |
| 5 | |
| 6 | Hashes - Simple wrapper around the hash functions |
| 7 | |
| 8 | This is just used to make building the methods simpler, this is the |
| 9 | only interface required.. |
| 10 | |
| 11 | ##################################################################### */ |
| 12 | /*}}}*/ |
| 13 | #ifndef APTPKG_HASHES_H |
| 14 | #define APTPKG_HASHES_H |
| 15 | |
| 16 | |
| 17 | #include <apt-pkg/md5.h> |
| 18 | #include <apt-pkg/sha1.h> |
| 19 | #include <apt-pkg/sha2.h> |
| 20 | #include <apt-pkg/macros.h> |
| 21 | |
| 22 | #include <cstring> |
| 23 | #include <string> |
| 24 | |
| 25 | #ifndef APT_8_CLEANER_HEADERS |
| 26 | using std::min; |
| 27 | using std::vector; |
| 28 | #endif |
| 29 | #ifndef APT_10_CLEANER_HEADERS |
| 30 | #include <apt-pkg/fileutl.h> |
| 31 | #include <algorithm> |
| 32 | #include <vector> |
| 33 | #endif |
| 34 | |
| 35 | |
| 36 | class FileFd; |
| 37 | |
| 38 | // helper class that contains hash function name |
| 39 | // and hash |
| 40 | class HashString |
| 41 | { |
| 42 | protected: |
| 43 | std::string Type; |
| 44 | std::string Hash; |
| 45 | static const char * _SupportedHashes[10]; |
| 46 | |
| 47 | // internal helper |
| 48 | std::string GetHashForFile(std::string filename) const; |
| 49 | |
| 50 | public: |
| 51 | HashString(std::string Type, std::string Hash); |
| 52 | HashString(std::string StringedHashString); // init from str as "type:hash" |
| 53 | HashString(); |
| 54 | |
| 55 | // get hash type used |
| 56 | std::string HashType() const { return Type; }; |
| 57 | std::string HashValue() const { return Hash; }; |
| 58 | APT_DEPRECATED std::string HashType() { return Type; }; |
| 59 | APT_DEPRECATED std::string HashValue() { return Hash; }; |
| 60 | |
| 61 | // verify the given filename against the currently loaded hash |
| 62 | bool VerifyFile(std::string filename) const; |
| 63 | |
| 64 | // generate a hash string from the given filename |
| 65 | bool FromFile(std::string filename); |
| 66 | |
| 67 | |
| 68 | // helper |
| 69 | std::string toStr() const; // convert to str as "type:hash" |
| 70 | bool empty() const; |
| 71 | bool operator==(HashString const &other) const; |
| 72 | bool operator!=(HashString const &other) const; |
| 73 | |
| 74 | // return the list of hashes we support |
| 75 | static APT_CONST const char** SupportedHashes(); |
| 76 | }; |
| 77 | |
| 78 | class HashStringList |
| 79 | { |
| 80 | public: |
| 81 | /** find best hash if no specific one is requested |
| 82 | * |
| 83 | * @param type of the checksum to return, can be \b NULL |
| 84 | * @return If type is \b NULL (or the empty string) it will |
| 85 | * return the 'best' hash; otherwise the hash which was |
| 86 | * specifically requested. If no hash is found \b NULL will be returned. |
| 87 | */ |
| 88 | HashString const * find(char const * const type) const; |
| 89 | HashString const * find(std::string const &type) const { return find(type.c_str()); } |
| 90 | |
| 91 | /** finds the filesize hash and returns it as number |
| 92 | * |
| 93 | * @return beware: if the size isn't known we return \b 0 here, |
| 94 | * just like we would do for an empty file. If that is a problem |
| 95 | * for you have to get the size manually out of the list. |
| 96 | */ |
| 97 | unsigned long long FileSize() const; |
| 98 | |
| 99 | /** sets the filesize hash |
| 100 | * |
| 101 | * @param Size of the file |
| 102 | * @return @see #push_back |
| 103 | */ |
| 104 | bool FileSize(unsigned long long const Size); |
| 105 | |
| 106 | /** check if the given hash type is supported |
| 107 | * |
| 108 | * @param type to check |
| 109 | * @return true if supported, otherwise false |
| 110 | */ |
| 111 | static APT_PURE bool supported(char const * const type); |
| 112 | /** add the given #HashString to the list |
| 113 | * |
| 114 | * @param hashString to add |
| 115 | * @return true if the hash is added because it is supported and |
| 116 | * not already a different hash of the same type included, otherwise false |
| 117 | */ |
| 118 | bool push_back(const HashString &hashString); |
| 119 | /** @return size of the list of HashStrings */ |
| 120 | size_t size() const { return list.size(); } |
| 121 | |
| 122 | /** take the 'best' hash and verify file with it |
| 123 | * |
| 124 | * @param filename to verify |
| 125 | * @return true if the file matches the hashsum, otherwise false |
| 126 | */ |
| 127 | bool VerifyFile(std::string filename) const; |
| 128 | |
| 129 | /** is the list empty ? |
| 130 | * |
| 131 | * @return \b true if the list is empty, otherwise \b false |
| 132 | */ |
| 133 | bool empty() const { return list.empty(); } |
| 134 | |
| 135 | /** has the list at least one good entry |
| 136 | * |
| 137 | * similar to #empty, but handles forced hashes. |
| 138 | * |
| 139 | * @return if no hash is forced, same result as #empty, |
| 140 | * if one is forced \b true if this has is available, \b false otherwise |
| 141 | */ |
| 142 | bool usable() const; |
| 143 | |
| 144 | typedef std::vector<HashString>::const_iterator const_iterator; |
| 145 | |
| 146 | /** iterator to the first element */ |
| 147 | const_iterator begin() const { return list.begin(); } |
| 148 | |
| 149 | /** iterator to the end element */ |
| 150 | const_iterator end() const { return list.end(); } |
| 151 | |
| 152 | /** start fresh with a clear list */ |
| 153 | void clear() { list.clear(); } |
| 154 | |
| 155 | /** compare two HashStringList for similarity. |
| 156 | * |
| 157 | * Two lists are similar if at least one hashtype is in both lists |
| 158 | * and the hashsum matches. All hashes are checked by default, |
| 159 | * if one doesn't match false is returned regardless of how many |
| 160 | * matched before. If a hash is forced, only this hash is compared, |
| 161 | * all others are ignored. |
| 162 | */ |
| 163 | bool operator==(HashStringList const &other) const; |
| 164 | bool operator!=(HashStringList const &other) const; |
| 165 | |
| 166 | HashStringList() {} |
| 167 | |
| 168 | // simplifying API-compatibility constructors |
| 169 | HashStringList(std::string const &hash) { |
| 170 | if (hash.empty() == false) |
| 171 | list.push_back(HashString(hash)); |
| 172 | } |
| 173 | HashStringList(char const * const hash) { |
| 174 | if (hash != NULL && hash[0] != '\0') |
| 175 | list.push_back(HashString(hash)); |
| 176 | } |
| 177 | |
| 178 | private: |
| 179 | std::vector<HashString> list; |
| 180 | }; |
| 181 | |
| 182 | class PrivateHashes; |
| 183 | class Hashes |
| 184 | { |
| 185 | PrivateHashes * const d; |
| 186 | |
| 187 | public: |
| 188 | /* those will disappear in the future as it is hard to add new ones this way. |
| 189 | * Use Add* to build the results and get them via GetHashStringList() instead */ |
| 190 | APT_DEPRECATED MD5Summation MD5; |
| 191 | APT_DEPRECATED SHA1Summation SHA1; |
| 192 | APT_DEPRECATED SHA256Summation SHA256; |
| 193 | APT_DEPRECATED SHA512Summation SHA512; |
| 194 | |
| 195 | static const int UntilEOF = 0; |
| 196 | |
| 197 | bool Add(const unsigned char * const Data, unsigned long long const Size); |
| 198 | APT_DEPRECATED bool Add(const unsigned char * const Data, unsigned long long const Size, unsigned int const Hashes); |
| 199 | inline bool Add(const char * const Data) |
| 200 | {return Add((unsigned char const * const)Data,strlen(Data));}; |
| 201 | inline bool Add(const unsigned char * const Beg,const unsigned char * const End) |
| 202 | {return Add(Beg,End-Beg);}; |
| 203 | |
| 204 | enum SupportedHashes { MD5SUM = (1 << 0), SHA1SUM = (1 << 1), SHA256SUM = (1 << 2), |
| 205 | SHA512SUM = (1 << 3) }; |
| 206 | bool AddFD(int const Fd,unsigned long long Size = 0); |
| 207 | APT_DEPRECATED bool AddFD(int const Fd,unsigned long long Size, unsigned int const Hashes); |
| 208 | bool AddFD(FileFd &Fd,unsigned long long Size = 0); |
| 209 | APT_DEPRECATED bool AddFD(FileFd &Fd,unsigned long long Size, unsigned int const Hashes); |
| 210 | |
| 211 | HashStringList GetHashStringList(); |
| 212 | |
| 213 | APT_IGNORE_DEPRECATED_PUSH |
| 214 | /** create a Hashes object to calculate all supported hashes |
| 215 | * |
| 216 | * If ALL is too much, you can limit which Hashes are calculated |
| 217 | * with the following other constructors which mention explicitly |
| 218 | * which hashes to generate. */ |
| 219 | Hashes(); |
| 220 | /** @param Hashes bitflag composed of #SupportedHashes */ |
| 221 | Hashes(unsigned int const Hashes); |
| 222 | /** @param Hashes is a list of hashes */ |
| 223 | Hashes(HashStringList const &Hashes); |
| 224 | virtual ~Hashes(); |
| 225 | APT_IGNORE_DEPRECATED_POP |
| 226 | |
| 227 | private: |
| 228 | APT_HIDDEN APT_CONST inline unsigned int boolsToFlag(bool const addMD5, bool const addSHA1, bool const addSHA256, bool const addSHA512) |
| 229 | { |
| 230 | unsigned int Hashes = ~0; |
| 231 | if (addMD5 == false) Hashes &= ~MD5SUM; |
| 232 | if (addSHA1 == false) Hashes &= ~SHA1SUM; |
| 233 | if (addSHA256 == false) Hashes &= ~SHA256SUM; |
| 234 | if (addSHA512 == false) Hashes &= ~SHA512SUM; |
| 235 | return Hashes; |
| 236 | } |
| 237 | |
| 238 | public: |
| 239 | APT_IGNORE_DEPRECATED_PUSH |
| 240 | APT_DEPRECATED bool AddFD(int const Fd, unsigned long long Size, bool const addMD5, |
| 241 | bool const addSHA1, bool const addSHA256, bool const addSHA512) { |
| 242 | return AddFD(Fd, Size, boolsToFlag(addMD5, addSHA1, addSHA256, addSHA512)); |
| 243 | }; |
| 244 | APT_DEPRECATED bool AddFD(FileFd &Fd, unsigned long long Size, bool const addMD5, |
| 245 | bool const addSHA1, bool const addSHA256, bool const addSHA512) { |
| 246 | return AddFD(Fd, Size, boolsToFlag(addMD5, addSHA1, addSHA256, addSHA512)); |
| 247 | }; |
| 248 | APT_IGNORE_DEPRECATED_POP |
| 249 | }; |
| 250 | |
| 251 | #endif |