Пример #1
0
    def test_verify_failing_first_party_general_caveats(self):
        m = Macaroon(
            location='http://mybank/',
            identifier='we used our secret key',
            key='this is our super secret key; only we should know it')
        m.add_first_party_caveat('general caveat')

        v = Verifier()
        v.satisfy_general(lambda _: False)
        with assert_raises(MacaroonInvalidSignatureException) as cm:
            v.verify(m, 'this is our super secret key; only we should know it')
Пример #2
0
def _verify_macaroon(mac):
    v = Verifier()
    #verify the role is valid
    v.satisfy_general(_role_verification)
    #verify username is valid, only checks to make sure it only contains ascii, could be improved.
    v.satisfy_general(_user_verification)
    f = open("/var/EMR/secret_key", "r")
    if f.mode == 'r':
        secret_key = f.read()
        return v.verify(mac, secret_key)
    return None
Пример #3
0
    def macaroon_ops(self, macaroons):
        ''' This method makes the oven satisfy the MacaroonOpStore protocol
        required by the Checker class.

        For macaroons minted with previous bakery versions, it always
        returns a single LoginOp operation.

        :param macaroons:
        :return:
        '''
        if len(macaroons) == 0:
            raise ValueError('no macaroons provided')

        storage_id, ops = _decode_macaroon_id(macaroons[0].identifier_bytes)
        root_key = self.root_keystore_for_ops(ops).get(storage_id)
        if root_key is None:
            raise VerificationError(
                'macaroon key not found in storage')
        v = Verifier()
        conditions = []

        def validator(condition):
            # Verify the macaroon's signature only. Don't check any of the
            # caveats yet but save them so that we can return them.
            conditions.append(condition)
            return True
        v.satisfy_general(validator)
        try:
            v.verify(macaroons[0], root_key, macaroons[1:])
        except Exception as exc:
            # Unfortunately pymacaroons doesn't control
            # the set of exceptions that can be raised here.
            # Possible candidates are:
            # pymacaroons.exceptions.MacaroonUnmetCaveatException
            # pymacaroons.exceptions.MacaroonInvalidSignatureException
            # ValueError
            # nacl.exceptions.CryptoError
            #
            # There may be others too, so just catch everything.
            raise six.raise_from(
                VerificationError('verification failed: {}'.format(str(exc))),
                exc,
            )

        if (self.ops_store is not None
            and len(ops) == 1
                and ops[0].entity.startswith('multi-')):
            # It's a multi-op entity, so retrieve the actual operations
            # it's associated with.
            ops = self.ops_store.get_ops(ops[0].entity)

        return ops, conditions
Пример #4
0
    def verify(self, session, discharge):
        session_macaroon = Macaroon.from_binary(session)
        discharge_macaroon = Macaroon.from_binary(discharge)

        self.logger.debug('Root Macaroon:\n' + session_macaroon.inspect())
        self.logger.debug('Discharge Macaroon:\n' +
                          discharge_macaroon.inspect())

        verifier = Verifier()
        verifier.satisfy_general(verify_time)
        verified = verifier.verify(session_macaroon,
                                   self.redis.get(session_macaroon.identifier),
                                   discharge_macaroons=[discharge_macaroon])
        return verified
Пример #5
0
    def test_verify_first_party_general_caveats(self):
        m = Macaroon(
            location='http://mybank/',
            identifier='we used our secret key',
            key='this is our super secret key; only we should know it')
        m.add_first_party_caveat('general caveat')

        def general_caveat_validator(predicate):
            return predicate == 'general caveat'

        v = Verifier()
        v.satisfy_general(general_caveat_validator)
        verified = v.verify(
            m, 'this is our super secret key; only we should know it')
        assert_true(verified)
Пример #6
0
    def test_verify_failing_first_party_general_caveats(self):
        m = Macaroon(
            location='http://mybank/',
            identifier='we used our secret key',
            key='this is our super secret key; only we should know it'
        )
        m.add_first_party_caveat('general caveat')

        v = Verifier()
        v.satisfy_general(lambda _: False)
        with assert_raises(MacaroonInvalidSignatureException) as cm:
            v.verify(
                m,
                'this is our super secret key; only we should know it'
            )
Пример #7
0
    def test_verify_first_party_general_caveats(self):
        m = Macaroon(
            location='http://mybank/',
            identifier='we used our secret key',
            key='this is our super secret key; only we should know it'
        )
        m.add_first_party_caveat('general caveat')

        def general_caveat_validator(predicate):
            return predicate == 'general caveat'

        v = Verifier()
        v.satisfy_general(general_caveat_validator)
        verified = v.verify(
            m,
            'this is our super secret key; only we should know it'
        )
        assert_true(verified)
Пример #8
0
    def macaroon_ops(self, macaroons):
        ''' This method makes the oven satisfy the MacaroonOpStore protocol
        required by the Checker class.

        For macaroons minted with previous bakery versions, it always
        returns a single LoginOp operation.

        :param macaroons:
        :return:
        '''
        if len(macaroons) == 0:
            raise ValueError('no macaroons provided')

        storage_id, ops = _decode_macaroon_id(macaroons[0].identifier_bytes)
        root_key = self.root_keystore_for_ops(ops).get(storage_id)
        if root_key is None:
            raise bakery.VerificationError(
                'macaroon key not found in storage')
        v = Verifier()
        conditions = []

        def validator(condition):
            # Verify the macaroon's signature only. Don't check any of the
            # caveats yet but save them so that we can return them.
            conditions.append(condition)
            return True
        v.satisfy_general(validator)
        try:
            v.verify(macaroons[0], root_key, macaroons[1:])
        except (MacaroonUnmetCaveatException,
                MacaroonInvalidSignatureException) as exc:
            raise bakery.VerificationError(
                'verification failed: {}'.format(exc.args[0]))

        if (self.ops_store is not None
            and len(ops) == 1
                and ops[0].entity.startswith('multi-')):
            # It's a multi-op entity, so retrieve the actual operations
            # it's associated with.
            ops = self.ops_store.get_ops(ops[0].entity)

        return ops, conditions
Пример #9
0
def gallery_token(token, image_name):

    if token:

        #Decode token
        n = Macaroon.deserialize(token)
        v = Verifier()

        form = forms.VerifyEmail()

        #On valid for submission
        if form.validate_on_submit():

            #Verify Macaroon is valid
            v.satisfy_exact('email = {}'.format(form.email.data))
            v.satisfy_exact('image_name = {}'.format(image_name))
            v.satisfy_general(check_expiry)

            try:
                verified = v.verify(n, keys[n.identifier])

                return send_from_directory(app.config['UPLOADED_IMAGES_DEST'],
                                           filename=image_name,
                                           as_attachment=False)
            except:
                flash("Unable to access")
                return render_template('validate_email.html',
                                       form=form,
                                       token=token,
                                       image_name=image_name)

        return render_template('validate_email.html',
                               form=form,
                               token=token,
                               image_name=image_name)

    else:
        flash("Unable to access")
        return render_template('validate_email.html',
                               form=form,
                               token=token,
                               image_name=image_name)
Пример #10
0
    def macaroon_ops(self, macaroons):
        ''' This method makes the oven satisfy the MacaroonOpStore protocol
        required by the Checker class.

        For macaroons minted with previous bakery versions, it always
        returns a single LoginOp operation.

        :param macaroons:
        :return:
        '''
        if len(macaroons) == 0:
            raise ValueError('no macaroons provided')

        storage_id, ops = _decode_macaroon_id(macaroons[0].identifier_bytes)
        root_key = self.root_keystore_for_ops(ops).get(storage_id)
        if root_key is None:
            raise bakery.VerificationError('macaroon key not found in storage')
        v = Verifier()
        conditions = []

        def validator(condition):
            # Verify the macaroon's signature only. Don't check any of the
            # caveats yet but save them so that we can return them.
            conditions.append(condition)
            return True

        v.satisfy_general(validator)
        try:
            v.verify(macaroons[0], root_key, macaroons[1:])
        except (MacaroonUnmetCaveatException,
                MacaroonInvalidSignatureException) as exc:
            raise bakery.VerificationError('verification failed: {}'.format(
                exc.args[0]))

        if (self.ops_store is not None and len(ops) == 1
                and ops[0].entity.startswith('multi-')):
            # It's a multi-op entity, so retrieve the actual operations
            # it's associated with.
            ops = self.ops_store.get_ops(ops[0].entity)

        return ops, conditions
Пример #11
0
def satisfy_expiry(v: pymacaroons.Verifier,
                   get_time_ms: Callable[[], int]) -> None:
    """Make a macaroon verifier which accepts 'time' caveats

    Builds a caveat verifier which will accept unexpired 'time' caveats, and adds it to
    the given macaroon verifier.

    Args:
        v: the macaroon verifier
        get_time_ms: a callable which will return the timestamp after which the caveat
            should be considered expired. Normally the current time.
    """
    def verify_expiry_caveat(caveat: str) -> bool:
        time_msec = get_time_ms()
        prefix = "time < "
        if not caveat.startswith(prefix):
            return False
        expiry = int(caveat[len(prefix):])
        return time_msec < expiry

    v.satisfy_general(verify_expiry_caveat)
Пример #12
0
def verify(
    macaroon: Macaroon,
    key: bytes,
    roles: List[str],
    caveats: List[str],
    used: int,
    req: Request,
) -> bool:
    assert macaroon
    v_obj = Verifier()

    v_obj.satisfy_exact(f"user = {macaroon.identifier}")
    for role in roles:
        v_obj.satisfy_exact(f"role = {role}")

    # satisfy specific actions in the API
    for caveat in caveats:
        v_obj.satisfy_exact(f"action = {caveat}")

    # satify same origin restrictions
    v_obj.satisfy_exact(f"origin = {req.headers['origin']}")

    # satisfy macaroon with time expiry
    v_obj.satisfy_general(lambda x: x.split(" = ")[0] == "expiry" and int(
        x.split(" = ")[1]) > time())

    # satisfy macaroon with limited uses
    v_obj.satisfy_general(lambda x: x.split(" = ")[0] == "uses" and int(
        x.split(" = ")[1]) > used)

    # satisfy any with 'amount' caveat. Currently only included so macaroon user can tell amount
    v_obj.satisfy_general(lambda x: x.split(" = ")[0] == "amount")

    return bool(v_obj.verify(macaroon, key))
Пример #13
0
    def verifyMacaroon(self,
                       macaroon,
                       context,
                       require_context=True,
                       errors=None,
                       **kwargs):
        """See `IMacaroonIssuer`."""
        if macaroon.location != config.vhost.mainsite.hostname:
            if errors is not None:
                errors.append("Macaroon has unknown location '%s'." %
                              macaroon.location)
            return None
        if require_context and context is None:
            if errors is not None:
                errors.append(
                    "Expected macaroon verification context but got None.")
            return None
        if context is not None:
            try:
                context = self.checkVerificationContext(context)
            except BadMacaroonContext as e:
                if errors is not None:
                    errors.append(str(e))
                return None
        seen = set()
        verified = MacaroonVerificationResult(self.identifier)

        def verify(caveat):
            try:
                caveat_name, caveat_value = caveat.split(" ", 1)
            except ValueError:
                if errors is not None:
                    errors.append("Cannot parse caveat '%s'." % caveat)
                return False
            if caveat_name not in self.allow_multiple and caveat_name in seen:
                if errors is not None:
                    errors.append("Multiple '%s' caveats are not allowed." %
                                  caveat_name)
                return False
            seen.add(caveat_name)
            if caveat_name == self._primary_caveat_name:
                checker = self.verifyPrimaryCaveat
            else:
                checker = self.checkers.get(caveat_name)
                if checker is None:
                    if errors is not None:
                        errors.append("Unhandled caveat name '%s'." %
                                      caveat_name)
                    return False
            if not checker(caveat_value, context, **kwargs):
                if errors is not None:
                    errors.append("Caveat check for '%s' failed." % caveat)
                return False
            return True

        try:
            verifier = Verifier()
            verifier.satisfy_general(verify)
            if verifier.verify(macaroon, self._root_secret):
                return verified
            else:
                return None
        # XXX cjwatson 2019-04-24: This can currently raise a number of
        # other exceptions in the presence of non-well-formed input data,
        # but most of them are too broad to reasonably catch so we let them
        # turn into OOPSes for now.  Revisit this once
        # https://github.com/ecordell/pymacaroons/issues/51 is fixed.
        except MacaroonVerificationFailedException as e:
            if errors is not None and not errors:
                errors.append(str(e))
            return None