Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Record the SSO Auth Provider in the login token #9510

Merged
merged 14 commits into from
Mar 4, 2021
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 24 additions & 3 deletions synapse/util/macaroons.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,18 @@

"""Utilities for manipulating macaroons"""

from typing import Callable
from typing import Callable, Optional

import pymacaroons
from pymacaroons.exceptions import MacaroonVerificationFailedException


def get_value_from_macaroon(macaroon: pymacaroons.Macaroon, key: str) -> str:
"""Extracts a caveat value from a macaroon token.

Checks that there is exactly one caveat of the form "key = <val>" in the macaroon,
and returns the extracted value.

Comment on lines +28 to +30
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is being introduced mostly in the interests of safety. We've been burnt badly by this in the past (https://matrix.org/blog/2016/07/08/critical-security-vulnerability-in-synapse-0-12-to-0-16-1-inclusive), so some double-checking feels like it is in order.

Args:
macaroon: the token
key: the key of the caveat to extract
Expand All @@ -33,11 +37,28 @@ def get_value_from_macaroon(macaroon: pymacaroons.Macaroon, key: str) -> str:

Raises:
KeyError: if the caveat was not in the macaroon
MacaroonVerificationFailedException: if there are conflicting values for the
caveat in the macaroon
"""
prefix = key + " = "
result = None # type: Optional[str]
for caveat in macaroon.caveats:
if caveat.caveat_id.startswith(prefix):
return caveat.caveat_id[len(prefix) :]
if not caveat.caveat_id.startswith(prefix):
continue

val = caveat.caveat_id[len(prefix) :]

if result is None:
# first time we found this caveat: record the value
result = val
elif val != result:
# on subsequent occurrences, raise if the value is different.
raise MacaroonVerificationFailedException(
"Conflicting values for caveat " + key
)

if result is not None:
return result
raise KeyError("No %s caveat in macaroon" % (key,))


Expand Down