/usr/lib/python3/dist-packages/simplestreams/checksum_util.py is in python3-simplestreams 0.1.0~bzr460-0ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | # Copyright (C) 2015 Canonical Ltd.
#
# Author: Scott Moser <scott.moser@canonical.com>
#
# Simplestreams is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# Simplestreams 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 Affero General Public
# License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with Simplestreams. If not, see <http://www.gnu.org/licenses/>.
import hashlib
# these are in order of increasing preference
CHECKSUMS = ("md5", "sha256", "sha512")
try:
ALGORITHMS = list(getattr(hashlib, 'algorithms'))
except AttributeError:
ALGORITHMS = list(hashlib.algorithms_available)
class checksummer(object):
_hasher = None
algorithm = None
expected = None
def __init__(self, checksums):
if not checksums:
self._hasher = None
return
for meth in CHECKSUMS:
if meth in checksums and meth in ALGORITHMS:
self._hasher = hashlib.new(meth)
self.algorithm = meth
self.expected = checksums.get(self.algorithm, None)
if not self._hasher:
raise TypeError("Unable to find suitable hash algorithm")
def update(self, data):
if self._hasher is None:
return
self._hasher.update(data)
def hexdigest(self):
if self._hasher is None:
return None
return self._hasher.hexdigest()
def check(self):
return (self.expected is None or self.expected == self.hexdigest())
def __str__(self):
return ("checksummer (algorithm=%s expected=%s)" %
(self.algorithm, self.expected))
def item_checksums(item):
return {k: item[k] for k in CHECKSUMS if k in item}
class SafeCheckSummer(checksummer):
"""SafeCheckSummer raises ValueError if checksums are not provided."""
def __init__(self, checksums, allowed=None):
if allowed is None:
allowed = CHECKSUMS
super(SafeCheckSummer, self).__init__(checksums)
if self.algorithm not in allowed:
raise ValueError(
"provided checksums (%s) did not include any allowed (%s)" %
(checksums, allowed))
class InvalidChecksum(ValueError):
def __init__(self, path, cksum, size=None, expected_size=None, msg=None):
self.path = path
self.cksum = cksum
self.size = size
self.expected_size = expected_size
self.msg = msg
def __str__(self):
if self.msg is not None:
return self.msg
if not isinstance(self.expected_size, int):
msg = "Invalid size '%s' at %s." % (self.expected_size, self.path)
else:
msg = ("Invalid %s Checksum at %s. Found %s. Expected %s. "
"read %s bytes expected %s bytes." %
(self.cksum.algorithm, self.path,
self.cksum.hexdigest(), self.cksum.expected,
self.size, self.expected_size))
if self.size:
msg += (" (size %s expected %s)" %
(self.size, self.expected_size))
return msg
def invalid_checksum_for_reader(reader, msg=None):
return InvalidChecksum(path=reader.url, cksum=reader.checksummer,
size=reader.bytes_read, expected_size=reader.size,
msg=msg)
|