| # |
| # |
| |
| # Copyright (C) 2006, 2007, 2010, 2011 Google Inc. |
| # |
| # This program is free software; you can redistribute it and/or modify |
| # it under the terms of the GNU General Public License as published by |
| # the Free Software Foundation; either version 2 of the License, or |
| # (at your option) any later version. |
| # |
| # This program is distributed in the hope that it will be useful, but |
| # WITHOUT ANY WARRANTY; without even the implied warranty of |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| # General Public License for more details. |
| # |
| # You should have received a copy of the GNU General Public License |
| # along with this program; if not, write to the Free Software |
| # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
| # 02110-1301, USA. |
| |
| """Utility functions for hashing. |
| |
| """ |
| |
| import os |
| import hmac |
| |
| from ganeti import compat |
| |
| |
| def Sha1Hmac(key, text, salt=None): |
| """Calculates the HMAC-SHA1 digest of a text. |
| |
| HMAC is defined in RFC2104. |
| |
| @type key: string |
| @param key: Secret key |
| @type text: string |
| |
| """ |
| if salt: |
| salted_text = salt + text |
| else: |
| salted_text = text |
| |
| return hmac.new(key, salted_text, compat.sha1).hexdigest() |
| |
| |
| def VerifySha1Hmac(key, text, digest, salt=None): |
| """Verifies the HMAC-SHA1 digest of a text. |
| |
| HMAC is defined in RFC2104. |
| |
| @type key: string |
| @param key: Secret key |
| @type text: string |
| @type digest: string |
| @param digest: Expected digest |
| @rtype: bool |
| @return: Whether HMAC-SHA1 digest matches |
| |
| """ |
| return digest.lower() == Sha1Hmac(key, text, salt=salt).lower() |
| |
| |
| def _FingerprintFile(filename): |
| """Compute the fingerprint of a file. |
| |
| If the file does not exist, a None will be returned |
| instead. |
| |
| @type filename: str |
| @param filename: the filename to checksum |
| @rtype: str |
| @return: the hex digest of the sha checksum of the contents |
| of the file |
| |
| """ |
| if not (os.path.exists(filename) and os.path.isfile(filename)): |
| return None |
| |
| f = open(filename) |
| |
| fp = compat.sha1_hash() |
| while True: |
| data = f.read(4096) |
| if not data: |
| break |
| |
| fp.update(data) |
| |
| return fp.hexdigest() |
| |
| |
| def FingerprintFiles(files): |
| """Compute fingerprints for a list of files. |
| |
| @type files: list |
| @param files: the list of filename to fingerprint |
| @rtype: dict |
| @return: a dictionary filename: fingerprint, holding only |
| existing files |
| |
| """ |
| ret = {} |
| |
| for filename in files: |
| cksum = _FingerprintFile(filename) |
| if cksum: |
| ret[filename] = cksum |
| |
| return ret |