/usr/lib/python3/dist-packages/pymacaroons/verifier.py is in python3-pymacaroons 0.13.0-1.
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 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | import binascii
try:
# py2.7.7+ and py3.3+ have native comparison support
from hmac import compare_digest as constant_time_compare
except ImportError:
from pymacaroons.utils import equals as constant_time_compare
from pymacaroons.binders import HashSignaturesBinder
from pymacaroons.exceptions import MacaroonInvalidSignatureException
from pymacaroons.caveat_delegates import (
FirstPartyCaveatVerifierDelegate,
ThirdPartyCaveatVerifierDelegate,
)
from pymacaroons.utils import (
convert_to_bytes,
convert_to_string,
generate_derived_key,
hmac_digest
)
class Verifier(object):
def __init__(self):
self.predicates = []
self.callbacks = [self.verify_exact]
self.calculated_signature = None
self.first_party_caveat_verifier_delegate = (
FirstPartyCaveatVerifierDelegate()
)
self.third_party_caveat_verifier_delegate = (
ThirdPartyCaveatVerifierDelegate()
)
def satisfy_exact(self, predicate):
if predicate is None:
raise TypeError('Predicate cannot be none.')
self.predicates.append(convert_to_string(predicate))
def satisfy_general(self, func):
if not hasattr(func, '__call__'):
raise TypeError('General caveat verifiers must be callable.')
self.callbacks.append(func)
def verify_exact(self, predicate):
return predicate in self.predicates
def verify(self, macaroon, key, discharge_macaroons=None):
key = generate_derived_key(convert_to_bytes(key))
return self.verify_discharge(
macaroon,
macaroon,
key,
discharge_macaroons
)
def verify_discharge(self, root, discharge, key, discharge_macaroons=None):
calculated_signature = hmac_digest(
key, discharge.identifier_bytes
)
calculated_signature = self._verify_caveats(
root, discharge, discharge_macaroons, calculated_signature
)
if root != discharge:
calculated_signature = binascii.unhexlify(
HashSignaturesBinder(root).bind_signature(
binascii.hexlify(calculated_signature)
)
)
if not self._signatures_match(
discharge.signature_bytes,
binascii.hexlify(calculated_signature)):
raise MacaroonInvalidSignatureException('Signatures do not match')
return True
def _verify_caveats(self, root, macaroon, discharge_macaroons, signature):
for caveat in macaroon.caveats:
if self._caveat_met(root,
caveat,
macaroon,
discharge_macaroons,
signature):
signature = self._update_signature(caveat, signature)
return signature
def _caveat_met(self, root, caveat, macaroon,
discharge_macaroons, signature):
if caveat.first_party():
return (
self
.first_party_caveat_verifier_delegate
.verify_first_party_caveat(self, caveat, signature)
)
else:
return (
self
.third_party_caveat_verifier_delegate
.verify_third_party_caveat(
self, caveat, root, macaroon,
discharge_macaroons, signature,
)
)
def _update_signature(self, caveat, signature):
if caveat.first_party():
return (
self
.first_party_caveat_verifier_delegate
.update_signature(signature, caveat)
)
else:
return (
self
.third_party_caveat_verifier_delegate
.update_signature(signature, caveat)
)
def _signatures_match(self, macaroon_signature, computed_signature):
return constant_time_compare(
convert_to_bytes(macaroon_signature),
convert_to_bytes(computed_signature)
)
|