matrix-org / synapse

Synapse: Matrix homeserver written in Python/Twisted.

Home Page:https://matrix-org.github.io/synapse

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Missing resident signature in `send_join` response

progval opened this issue · comments

Description

About the event field in the send_join response, the spec says:

Required if the room version supports restricted join rules. The signed copy of the membership event sent to other servers by the resident server, including the resident server’s signature.

However, it seems Synapse is not including its own signature in send_join responses.

This is an issue for Conduit, which requires this signature to be present

Steps to reproduce

Send this request to matrix.org:

matrix.org PUT https://matrix.org/_matrix/federation/v2/send_join/%21YllBCgVdcoakoavZvX%3Arycee.net/@valtest:magnesium.test.progval.net
{
  "auth_events": [
    "$0pt22mJ5ZFjIdguJmKzZyBjhMQGEzOgtoe_3IwqE8KY",
    "$LR-AN_TTZyWaFQ9mbw5mW4S_pWgOEx6yWGq49tQertc",
    "$B8NBX6oUzLTq8OuFK_YvCJhqn2P_0fARY29XSZ6T3DA",
    "$2KkS9P38uz-lNpJi17LlKuLwzTkC3j4OTNB0mZT3wqs"
  ],
  "prev_events": [ "$2KkS9P38uz-lNpJi17LlKuLwzTkC3j4OTNB0mZT3wqs" ],
  "type": "m.room.member",
  "room_id": "!YllBCgVdcoakoavZvX:rycee.net",
  "sender": "@valtest:magnesium.test.progval.net",
  "content": { "membership": "join" },
  "depth": 30072,
  "state_key": "@valtest:magnesium.test.progval.net",
  "origin": "matrix.org",
  "origin_server_ts": 1701629808418,
  "hashes": { "sha256": "04LiiqR+T60gMM4HAEsjt+todsfvia0m8LBdZ6eemO4" },
  "signatures": {
    "magnesium.test.progval.net": { "ed25519:key2": "DPxUXxcLoLKLjFSrei6AVMj9sx7AUXb0dJ6i7nGhemaeM0reqzX6pNJXFgzxkLmHP4mCP1Je5f9Xcq13Z8e/CA" }
  }
} 

and read the response:

{
  "event": {
    "auth_events": [
      "$0pt22mJ5ZFjIdguJmKzZyBjhMQGEzOgtoe_3IwqE8KY",
      "$LR-AN_TTZyWaFQ9mbw5mW4S_pWgOEx6yWGq49tQertc",
      "$B8NBX6oUzLTq8OuFK_YvCJhqn2P_0fARY29XSZ6T3DA",
      "$2KkS9P38uz-lNpJi17LlKuLwzTkC3j4OTNB0mZT3wqs"
    ],
    "prev_events": [ "$2KkS9P38uz-lNpJi17LlKuLwzTkC3j4OTNB0mZT3wqs" ],
    "type": "m.room.member",
    "room_id": "!YllBCgVdcoakoavZvX:rycee.net",
    "sender": "@valtest:magnesium.test.progval.net",
    "content": { "membership": "join" },
    "depth": 30072,
    "state_key": "@valtest:magnesium.test.progval.net",
    "origin": "matrix.org",
    "origin_server_ts": 1701629808418,
    "hashes": { "sha256": "04LiiqR+T60gMM4HAEsjt+todsfvia0m8LBdZ6eemO4" },
    "signatures": {
      "magnesium.test.progval.net": { "ed25519:key2": "DPxUXxcLoLKLjFSrei6AVMj9sx7AUXb0dJ6i7nGhemaeM0reqzX6pNJXFgzxkLmHP4mCP1Je5f9Xcq13Z8e/CA" }
    },
    "unsigned": { "replaces_state": "$2KkS9P38uz-lNpJi17LlKuLwzTkC3j4OTNB0mZT3wqs" }
  }
  // ...
}

Notice there is only the joining HS's signature and not matrix.org's.

Homeserver

matrix.org

Synapse Version

both on 1.95.1 and 1.96.1 (b=matrix-org-hotfixes,9c3b906b3a)

Installation Method

I don't know

Database

postgresql

Workers

Multiple workers

Platform

n/a

Configuration

No response

Relevant log output

n/a

Anything else that would be useful to know?

No response

Good spot---thank you.

Synapse's response comes from:

event_json = event.get_pdu_json(time_now)
resp = {
"event": event_json,

Which calls get_dict and hence should include any signatures already present on the event object. Will need to dig a little deeper to understand where the resident server's signature should be generated by Synapse.

I would guess we need code like

event.signatures.update(
compute_event_signature(
room_version,
event.get_pdu_json(),
self.hs.hostname,
self.hs.signing_key,
)
)
somewhere in the send_join path.

Oh, actually we do have this logic: but we only seem to provide a signature when the /send_join is a restricted join (i.e. via a space):

# Sign the event since we're vouching on behalf of the remote server that
# the event is valid to be sent into the room. Currently this is only done
# if the user is being joined via restricted join rules.
if (
room_version.restricted_join_rule
and event.membership == Membership.JOIN
and EventContentFields.AUTHORISING_USER in event.content
):

It might be that the text of the spec is misleading here? But then again, I don't understand why a nonrestricted join wouldn't require a signature either?