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

Commit 9b74330

Browse files
Bubujcgruenhage
andcommitted
MSC3383: include destination in X-Matrix auth header
matrix-org/matrix-spec-proposals#3383 Co-Authored-By: Jan Christian Grünhage <[email protected]> Signed-off-by: Jan Christian Grünhage <[email protected]> Signed-off-by: Marcus Hoffmann <[email protected]>
1 parent e5c5e21 commit 9b74330

File tree

4 files changed

+32
-6
lines changed

4 files changed

+32
-6
lines changed

changelog.d/11398.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
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.

scripts-dev/federation_client.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,12 @@ def request(
105105
authorization_headers = []
106106

107107
for key, sig in signed_json["signatures"][origin_name].items():
108-
header = 'X-Matrix origin=%s,key="%s",sig="%s"' % (origin_name, key, sig)
108+
header = 'X-Matrix origin=%s,key="%s",sig="%s",destination="%s"' % (
109+
origin_name,
110+
key,
111+
sig,
112+
destination,
113+
)
109114
authorization_headers.append(header.encode("ascii"))
110115
print("Authorization: %s" % header, file=sys.stderr)
111116

synapse/federation/transport/server/_base.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,15 @@ async def authenticate_request(self, request, content):
8282

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

89+
# if the origin_server sent a destination along it needs to match our own server_name
90+
if destination is not None and destination != self.server_name:
91+
raise AuthenticationError(
92+
400, "Destination mismatch in auth header", Codes.UNAUTHORIZED
93+
)
8994
if (
9095
self.federation_domain_whitelist is not None
9196
and origin not in self.federation_domain_whitelist
@@ -140,7 +145,7 @@ def _parse_auth_header(header_bytes):
140145
header_bytes (bytes): header value
141146
142147
Returns:
143-
Tuple[str, str, str]: origin, key id, signature.
148+
Tuple[str, str, str, Optional[str]]: origin, key id, signature, destination.
144149
145150
Raises:
146151
AuthenticationError if the header could not be parsed
@@ -163,7 +168,14 @@ def strip_quotes(value):
163168

164169
key = strip_quotes(param_dict["key"])
165170
sig = strip_quotes(param_dict["sig"])
166-
return origin, key, sig
171+
172+
# get the destination server_name from the auth header if it exists
173+
if param_dict.get("destination") is not None:
174+
destination = strip_quotes(param_dict.get("destination"))
175+
else:
176+
destination = None
177+
178+
return origin, key, sig, destination
167179
except Exception as e:
168180
logger.warning(
169181
"Error parsing auth header '%s': %s",

synapse/http/matrixfederationclient.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,9 @@ def build_auth_headers(
715715
Returns:
716716
A list of headers to be added as "Authorization:" headers
717717
"""
718+
if destination is None and destination_is is None:
719+
raise ValueError("destination and destination_is cannot both be None!")
720+
718721
request: JsonDict = {
719722
"method": method.decode("ascii"),
720723
"uri": url_bytes.decode("ascii"),
@@ -737,8 +740,13 @@ def build_auth_headers(
737740
for key, sig in request["signatures"][self.server_name].items():
738741
auth_headers.append(
739742
(
740-
'X-Matrix origin=%s,key="%s",sig="%s"'
741-
% (self.server_name, key, sig)
743+
'X-Matrix origin=%s,key="%s",sig="%s",destination="%s"'
744+
% (
745+
self.server_name,
746+
key,
747+
sig,
748+
request.get("destination") or request["destination_is"],
749+
)
742750
).encode("ascii")
743751
)
744752
return auth_headers

0 commit comments

Comments
 (0)