def alice_server_access_service():
    macaroon_cookie = request.cookies.get('macaroonCookie')
    discharge_cookie = request.cookies.get('macaroonDischargeCookie')
    if macaroon_cookie is not None and macaroon_cookie != "" and discharge_cookie is not None and discharge_cookie != "":
        m = Macaroon.deserialize(macaroon_cookie)
        dm = Macaroon.deserialize(discharge_cookie)
        # Should be done on the client
        pm = m.prepare_for_request(dm)
        v = Verifier()
        try:
            verified = v.verify(m, alice_server_keys[m.identifier], [pm])
        except MacaroonInvalidSignatureException:
            verified = False
        if verified:
            resp = make_response(
                render_template("auth_demo.html",
                                result="Successful Authentication"))
        else:
            resp = make_response(
                render_template("auth_demo.html", result="Auth failed"))
        return resp
    else:
        resp = make_response(
            render_template(
                "auth_demo.html",
                result="Couldn't get necessary macaroons from cookies"))
        return resp
Пример #2
0
def assert_macaroon(m, discharge, version):
    assert_equal(m.location, 'my location')
    assert_equal(m.version, version)
    assert_equal(m.identifier_bytes, b'my identifier')
    v = Verifier(discharge_macaroons=[discharge])
    v.satisfy_exact('fp caveat')
    verified = v.verify(
        m,
        "my secret key",
    )
    assert_true(verified)
Пример #3
0
def assert_macaroon(m, discharge, version):
    assert_equal(m.location, 'my location')
    assert_equal(m.version, version)
    assert_equal(m.identifier_bytes, b'my identifier')
    v = Verifier(discharge_macaroons=[discharge])
    v.satisfy_exact('fp caveat')
    verified = v.verify(
        m,
        "my secret key",
    )
    assert_true(verified)
Пример #4
0
 def test_verify_first_party_exact_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('test = caveat')
     v = Verifier()
     v.satisfy_exact('test = caveat')
     verified = v.verify(
         m, 'this is our super secret key; only we should know it')
     assert_true(verified)
Пример #5
0
 def test_verify_first_party_exact_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('test = caveat')
     v = Verifier()
     v.satisfy_exact('test = caveat')
     verified = v.verify(
         m,
         'this is our super secret key; only we should know it'
     )
     assert_true(verified)
Пример #6
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
Пример #7
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'
            )
Пример #8
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)
Пример #9
0
    def test_verify_third_party_caveats_multi_level(self):
        # See https://github.com/ecordell/pymacaroons/issues/37
        root = Macaroon(location="", identifier="root-id", key="root-key")
        root.add_third_party_caveat("bob", "bob-caveat-root-key",
                                    "bob-is-great")

        # Create a discharge macaroon that requires a secondary discharge.
        discharge1 = Macaroon(location="bob",
                              identifier="bob-is-great",
                              key="bob-caveat-root-key")
        discharge1.add_third_party_caveat("barbara", "barbara-caveat-root-key",
                                          "barbara-is-great")

        # Create the secondary discharge macaroon.
        discharge2 = Macaroon(location="barbara",
                              identifier="barbara-is-great",
                              key="barbara-caveat-root-key")

        # Prepare the discharge macaroons for request.
        discharge1 = root.prepare_for_request(discharge1)
        discharge2 = root.prepare_for_request(discharge2)

        verified = Verifier(
            discharge_macaroons=[discharge1, discharge2]).verify(
                root, "root-key")
        assert_true(verified)
    def test_verify_encrypted_first_party_exact_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.first_party_caveat_delegate = EncryptedFirstPartyCaveatDelegate()
        m.add_first_party_caveat('test = caveat', encrypted=True)

        v = Verifier()
        v.first_party_caveat_verifier_delegate = EncryptedFirstPartyCaveatVerifierDelegate()
        v.satisfy_exact('test = caveat')
        verified = v.verify(
            m,
            'this is our super secret key; only we should know it'
        )
        assert_true(verified)
Пример #11
0
    def test_verify_third_party_caveats(self):
        m = Macaroon(
            location='http://mybank/',
            identifier='we used our other secret key',
            key='this is a different super-secret key; \
never use the same secret twice'
        )
        m.add_first_party_caveat('account = 3735928559')
        caveat_key = '4; guaranteed random by a fair toss of the dice'
        identifier = 'this was how we remind auth of key/pred'
        m.add_third_party_caveat('http://auth.mybank/', caveat_key, identifier)

        discharge = Macaroon(
            location='http://auth.mybank/',
            key=caveat_key,
            identifier=identifier
        )
        discharge.add_first_party_caveat('time < 2015-01-01T00:00')
        protected = m.prepare_for_request(discharge)

        v = Verifier()
        v.satisfy_exact('account = 3735928559')
        v.satisfy_exact('time < 2015-01-01T00:00')
        verified = v.verify(
            m,
            'this is a different super-secret key; \
never use the same secret twice',
            discharge_macaroons=[protected]
        )
        assert_true(verified)
Пример #12
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)
def photo_album():
    macaroonCookie = request.cookies.get('macaroonCookie')
    if macaroonCookie is not None and macaroonCookie != "":
        m = Macaroon.deserialize(macaroonCookie)
        v = Verifier()
        v.satisfy_exact('view_pictures = True')
        try:
            verified = v.verify(m, keys[m.identifier])
        except MacaroonInvalidSignatureException:
            verified = False
        images = [True, True, True]
        resp = make_response(
            render_template("home.html",
                            showimages=verified,
                            images=images,
                            macaroon=m.inspect().replace("\n", "<br/>")))
        return resp
    else:
        return redirect(url_for("login"))
Пример #14
0
 def test_mutual_discharge(self):
     m1 = Macaroon(location="", identifier="root-id", key="root-key")
     m1.add_third_party_caveat("bob", "bob-caveat-root-key", "bob-is-great")
     m2 = Macaroon(location="bob",
                   identifier="bob-is-great",
                   key="bob-caveat-root-key")
     m2.add_third_party_caveat("charlie", "bob-caveat-root-key",
                               "bob-is-great")
     m2 = m1.prepare_for_request(m2)
     Verifier(discharge_macaroons=[m2]).verify(m1, "root-key")
Пример #15
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
Пример #16
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)
Пример #17
0
    def test_verify_third_party_caveats(self):
        m = Macaroon(
            location='http://mybank/',
            identifier='we used our other secret key',
            key='this is a different super-secret key; \
never use the same secret twice'
        )
        m.add_first_party_caveat('account = 3735928559')
        caveat_key = '4; guaranteed random by a fair toss of the dice'
        identifier = 'this was how we remind auth of key/pred'
        m.add_third_party_caveat('http://auth.mybank/', caveat_key, identifier)

        discharge = Macaroon(
            location='http://auth.mybank/',
            key=caveat_key,
            identifier=identifier
        )
        discharge.add_first_party_caveat('time < 2015-01-01T00:00')
        protected = m.prepare_for_request(discharge)

        v = Verifier()
        v.satisfy_exact('account = 3735928559')
        v.satisfy_exact('time < 2015-01-01T00:00')
        verified = v.verify(
            m,
            'this is a different super-secret key; \
never use the same secret twice',
            discharge_macaroons=[protected]
        )
        assert_true(verified)
Пример #18
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
Пример #19
0
 def match(self, macaroons):
     mismatch = Contains("root").match(macaroons)
     if mismatch is not None:
         return mismatch
     root_macaroon = Macaroon.deserialize(macaroons["root"])
     if "discharge" in macaroons:
         discharge_macaroons = [
             Macaroon.deserialize(macaroons["discharge"])]
     else:
         discharge_macaroons = []
     try:
         Verifier().verify(root_macaroon, self.key, discharge_macaroons)
     except Exception as e:
         return Mismatch("Macaroons do not verify: %s" % e)
Пример #20
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')
Пример #21
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
def access_picture_with_macaroon(picture_id, macaroon):

    m = Macaroon.deserialize(macaroon)
    v = Verifier()
    v.satisfy_exact('view_pictures = True')
    v.satisfy_exact('picture_id = ' + str(picture_id))
    try:
        verified = v.verify(m, keys[m.identifier])
    except MacaroonInvalidSignatureException:
        verified = False
    images = [False, False, False]
    images[picture_id] = True
    resp = make_response(
        render_template("home.html",
                        showimages=verified,
                        images=images,
                        macaroon=m.inspect().replace("\n", "<br/>")))
    return resp
Пример #23
0
    def test_verify_encrypted_first_party_exact_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.first_party_caveat_delegate = EncryptedFirstPartyCaveatDelegate()
        m.add_first_party_caveat('test = caveat', encrypted=True)

        v = Verifier()
        v.first_party_caveat_verifier_delegate = EncryptedFirstPartyCaveatVerifierDelegate(
        )
        v.satisfy_exact('test = caveat')
        verified = v.verify(
            m, 'this is our super secret key; only we should know it')
        assert_true(verified)
Пример #24
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)
Пример #25
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
Пример #26
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
Пример #27
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))