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

make handling of federation Authorization header (more) compliant with RFC7230 #12774

Merged
merged 4 commits into from
May 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
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
1 change: 1 addition & 0 deletions changelog.d/12774.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Make handling of federation Authorization header (more) compliant with RFC7230.
8 changes: 5 additions & 3 deletions synapse/federation/transport/server/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,14 +169,16 @@ def _parse_auth_header(header_bytes: bytes) -> Tuple[str, str, str, Optional[str
"""
try:
header_str = header_bytes.decode("utf-8")
params = header_str.split(" ")[1].split(",")
params = re.split(" +", header_str)[1].split(",")
param_dict: Dict[str, str] = {
k: v for k, v in [param.split("=", maxsplit=1) for param in params]
k.lower(): v for k, v in [param.split("=", maxsplit=1) for param in params]
}

def strip_quotes(value: str) -> str:
if value.startswith('"'):
return value[1:-1]
return re.sub(
"\\\\(.)", lambda matchobj: matchobj.group(1), value[1:-1]
)
else:
return value

Expand Down
2 changes: 1 addition & 1 deletion synapse/http/matrixfederationclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -747,7 +747,7 @@ 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",destination="%s"'
'X-Matrix origin="%s",key="%s",sig="%s",destination="%s"'
% (
self.server_name,
key,
Expand Down
29 changes: 28 additions & 1 deletion tests/federation/transport/server/test__base.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

from synapse.api.errors import Codes
from synapse.federation.transport.server import BaseFederationServlet
from synapse.federation.transport.server._base import Authenticator
from synapse.federation.transport.server._base import Authenticator, _parse_auth_header
from synapse.http.server import JsonResource, cancellable
from synapse.server import HomeServer
from synapse.types import JsonDict
Expand Down Expand Up @@ -112,3 +112,30 @@ def test_uncancellable_disconnect(self) -> None:
expect_cancellation=False,
expected_body={"result": True},
)


class BaseFederationAuthorizationTests(unittest.TestCase):
def test_authorization_header(self) -> None:
"""Tests that the Authorization header is parsed correctly."""

# test a "normal" Authorization header
self.assertEqual(
_parse_auth_header(
b'X-Matrix origin=foo,key="ed25519:1",sig="sig",destination="bar"'
),
("foo", "ed25519:1", "sig", "bar"),
)
# test an Authorization with extra spaces, upper-case names, and escaped
# characters
self.assertEqual(
_parse_auth_header(
b'X-Matrix ORIGIN=foo,KEY="ed25\\519:1",SIG="sig",destination="bar"'
),
("foo", "ed25519:1", "sig", "bar"),
)
self.assertEqual(
_parse_auth_header(
b'X-Matrix origin=foo,key="ed25519:1",sig="sig",destination="bar",extra_field=ignored'
),
("foo", "ed25519:1", "sig", "bar"),
)