Skip to content

Commit

Permalink
MSC3383: include destination in X-Matrix auth header
Browse files Browse the repository at this point in the history
matrix-org/matrix-spec-proposals#3383

Co-Authored-By: Jan Christian Grünhage <jan.christian@gruenhage.xyz>
Signed-off-by: Jan Christian Grünhage <jan.christian@gruenhage.xyz>
Signed-off-by: Marcus Hoffmann <bubu@bubu1.eu>
  • Loading branch information
Bubu and jcgruenhage committed Nov 27, 2021
1 parent e5c5e21 commit 9b74330
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 6 deletions.
1 change: 1 addition & 0 deletions changelog.d/11398.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Implement [MSC3383](https://github.com/matrix-org/matrix-doc/pull/3383) for including the destination in server-to-server authentication headers. Contributed by @Bubu and @jcgruenhage for Famedly GmbH.
7 changes: 6 additions & 1 deletion scripts-dev/federation_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,12 @@ def request(
authorization_headers = []

for key, sig in signed_json["signatures"][origin_name].items():
header = 'X-Matrix origin=%s,key="%s",sig="%s"' % (origin_name, key, sig)
header = 'X-Matrix origin=%s,key="%s",sig="%s",destination="%s"' % (
origin_name,
key,
sig,
destination,
)
authorization_headers.append(header.encode("ascii"))
print("Authorization: %s" % header, file=sys.stderr)

Expand Down
18 changes: 15 additions & 3 deletions synapse/federation/transport/server/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,15 @@ async def authenticate_request(self, request, content):

for auth in auth_headers:
if auth.startswith(b"X-Matrix"):
(origin, key, sig) = _parse_auth_header(auth)
(origin, key, sig, destination) = _parse_auth_header(auth)
json_request["origin"] = origin
json_request["signatures"].setdefault(origin, {})[key] = sig

# if the origin_server sent a destination along it needs to match our own server_name
if destination is not None and destination != self.server_name:
raise AuthenticationError(
400, "Destination mismatch in auth header", Codes.UNAUTHORIZED
)
if (
self.federation_domain_whitelist is not None
and origin not in self.federation_domain_whitelist
Expand Down Expand Up @@ -140,7 +145,7 @@ def _parse_auth_header(header_bytes):
header_bytes (bytes): header value
Returns:
Tuple[str, str, str]: origin, key id, signature.
Tuple[str, str, str, Optional[str]]: origin, key id, signature, destination.
Raises:
AuthenticationError if the header could not be parsed
Expand All @@ -163,7 +168,14 @@ def strip_quotes(value):

key = strip_quotes(param_dict["key"])
sig = strip_quotes(param_dict["sig"])
return origin, key, sig

# get the destination server_name from the auth header if it exists
if param_dict.get("destination") is not None:
destination = strip_quotes(param_dict.get("destination"))
else:
destination = None

return origin, key, sig, destination
except Exception as e:
logger.warning(
"Error parsing auth header '%s': %s",
Expand Down
12 changes: 10 additions & 2 deletions synapse/http/matrixfederationclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,9 @@ def build_auth_headers(
Returns:
A list of headers to be added as "Authorization:" headers
"""
if destination is None and destination_is is None:
raise ValueError("destination and destination_is cannot both be None!")

request: JsonDict = {
"method": method.decode("ascii"),
"uri": url_bytes.decode("ascii"),
Expand All @@ -737,8 +740,13 @@ def build_auth_headers(
for key, sig in request["signatures"][self.server_name].items():
auth_headers.append(
(
'X-Matrix origin=%s,key="%s",sig="%s"'
% (self.server_name, key, sig)
'X-Matrix origin=%s,key="%s",sig="%s",destination="%s"'
% (
self.server_name,
key,
sig,
request.get("destination") or request["destination_is"],
)
).encode("ascii")
)
return auth_headers
Expand Down

0 comments on commit 9b74330

Please sign in to comment.