blob: 49c56bede98c57d7f6181872ab55ba30e9a847b3 [file] [log] [blame]
#
#
# Copyright (C) 2006, 2007, 2010, 2011 Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""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