Better specify what packages to install
[ganeti-local] / lib / utils / hash.py
1 #
2 #
3
4 # Copyright (C) 2006, 2007, 2010, 2011 Google Inc.
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 # General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 # 02110-1301, USA.
20
21 """Utility functions for hashing.
22
23 """
24
25 import os
26 import hmac
27
28 from ganeti import compat
29
30
31 def Sha1Hmac(key, text, salt=None):
32   """Calculates the HMAC-SHA1 digest of a text.
33
34   HMAC is defined in RFC2104.
35
36   @type key: string
37   @param key: Secret key
38   @type text: string
39
40   """
41   if salt:
42     salted_text = salt + text
43   else:
44     salted_text = text
45
46   return hmac.new(key, salted_text, compat.sha1).hexdigest()
47
48
49 def VerifySha1Hmac(key, text, digest, salt=None):
50   """Verifies the HMAC-SHA1 digest of a text.
51
52   HMAC is defined in RFC2104.
53
54   @type key: string
55   @param key: Secret key
56   @type text: string
57   @type digest: string
58   @param digest: Expected digest
59   @rtype: bool
60   @return: Whether HMAC-SHA1 digest matches
61
62   """
63   return digest.lower() == Sha1Hmac(key, text, salt=salt).lower()
64
65
66 def _FingerprintFile(filename):
67   """Compute the fingerprint of a file.
68
69   If the file does not exist, a None will be returned
70   instead.
71
72   @type filename: str
73   @param filename: the filename to checksum
74   @rtype: str
75   @return: the hex digest of the sha checksum of the contents
76       of the file
77
78   """
79   if not (os.path.exists(filename) and os.path.isfile(filename)):
80     return None
81
82   f = open(filename)
83
84   fp = compat.sha1_hash()
85   while True:
86     data = f.read(4096)
87     if not data:
88       break
89
90     fp.update(data)
91
92   return fp.hexdigest()
93
94
95 def FingerprintFiles(files):
96   """Compute fingerprints for a list of files.
97
98   @type files: list
99   @param files: the list of filename to fingerprint
100   @rtype: dict
101   @return: a dictionary filename: fingerprint, holding only
102       existing files
103
104   """
105   ret = {}
106
107   for filename in files:
108     cksum = _FingerprintFile(filename)
109     if cksum:
110       ret[filename] = cksum
111
112   return ret