From 4f655247b047136970d06c826697130d7ad31fe6 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 21 Aug 2019 21:17:41 -0700 Subject: [PATCH 01/63] initial draft of verification in DMs --- proposals/xxxx-e2e-verification-in-dms.md | 102 ++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 proposals/xxxx-e2e-verification-in-dms.md diff --git a/proposals/xxxx-e2e-verification-in-dms.md b/proposals/xxxx-e2e-verification-in-dms.md new file mode 100644 index 00000000..14b706dd --- /dev/null +++ b/proposals/xxxx-e2e-verification-in-dms.md @@ -0,0 +1,102 @@ +# Key verification in DMs + +Currently, key verification is done using `to_device` messages. However, since +`to_device` messages are not part of a timeline, there is no user-visible record +of the key verification. + +## Proposal + +The current [key verification +framework](https://matrix.org/docs/spec/client_server/r0.5.0#key-verification-framework) +will be replaced by a new framework that uses room messages rather than +`to_device` messages. Key verification messages will be sent in a [Direct +Messaging](https://matrix.org/docs/spec/client_server/r0.5.0#id185) room. If +there is no Direct Messaging room between the two users involved, the client +that initiates the key verification will create one. + +In this proposal, we use "Alice" to denote the user who initiates the key +verification, and "Bob" to denote the other user involved in the key +verification. + +### General framework + +#### Requesting a key verification + +To request a key verification, Alice will send an `m.room.message` event with the +following properties in its contents: + +- `body`: a fallback message to alert users that their client does not support + the key verification framework, and that they should use a different method + to verify keys +- `msgtype`: `m.key.verification.request` +- `methods`: the verification methods supported by Alice's client + +Key verifications will be identified by the event ID of the key verification +request event. + +Clients should ignore verification requests that have been accepted or cancelled. + +#### Accepting a key verification + +To accept a key verification, Bob will send an `m.key.verification.start` event +with the following properties in its contents: + +- `m.relates_to`: an object with the properties: + - `rel_type`: `m.key.verification` + - `event_id`: the event ID of the key verification request that is being + accepted +- `method`: the key verification method that is being used + +Clients should ignore `m.key.verification.start` events that correspond to +verification requests that it did not send. + +Clients may use this event as a place in the room's timeline do display +progress of the key verification process and to interact with the user as +necessary. + +#### Rejecting a key verification + +To reject a key verification, Bob will send an `m.key.verification.cancel` +event with the following properties in its contents: + +- `m.relates_to`: an object with the properties: + - `rel_type`: `m.key.verification` + - `event_id`: the event ID of the key verification that is being cancelled +- `body`: A human readable description of the `code`. The client should only + rely on this string if it does not understand the `code`. +- `code`: The error code for why the process/request was cancelled by the + user. The contents are the same as the `code` property of the currently + defined [`m.key.verification.cancel` to-device + event](https://matrix.org/docs/spec/client_server/r0.5.0#m-key-verification-cancel) + +This message may be sent at any point in the key verification process. Any +subsequent key verification messages relating to the same request are ignored. +However, this does not undo any verifications that have already been done. + +#### Other events + +Key verification methods may define their own event types, or extensions to the +above event types. All events sent as part of a key verification process +should have an `m.relates_to` property as defined for +`m.key.verification.accept` or `m.key.verification.cancel` events. + +Clients should ignore events with an `m.relates_to` that have a `rel_type` of +`m.key.verification` that refer to a verification where it is not the requester +nor the accepter. + +### SAS verification + +The messages used in SAS verification are the same as those currently defined, +except that instead of the `transaction_id` property, an `m.relates_to` +property, as defined above, is used instead. + +## Tradeoffs + + +## Potential issues + + +## Security considerations + + +## Conclusion From fb724bc625f0e0ea89284eeb5463c3d732ecbec1 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 21 Aug 2019 21:22:03 -0700 Subject: [PATCH 02/63] rename to match PR number --- ...e2e-verification-in-dms.md => 2241-e2e-verification-in-dms.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename proposals/{xxxx-e2e-verification-in-dms.md => 2241-e2e-verification-in-dms.md} (100%) diff --git a/proposals/xxxx-e2e-verification-in-dms.md b/proposals/2241-e2e-verification-in-dms.md similarity index 100% rename from proposals/xxxx-e2e-verification-in-dms.md rename to proposals/2241-e2e-verification-in-dms.md From 0e6286f5d062361688bf6fcd2ff3e084866d33c2 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Sat, 24 Aug 2019 12:38:13 -0700 Subject: [PATCH 03/63] write more stuff --- proposals/2241-e2e-verification-in-dms.md | 58 +++++++++++++++++++++-- 1 file changed, 54 insertions(+), 4 deletions(-) diff --git a/proposals/2241-e2e-verification-in-dms.md b/proposals/2241-e2e-verification-in-dms.md index 14b706dd..8f98ac2e 100644 --- a/proposals/2241-e2e-verification-in-dms.md +++ b/proposals/2241-e2e-verification-in-dms.md @@ -1,8 +1,15 @@ # Key verification in DMs Currently, key verification is done using `to_device` messages. However, since -`to_device` messages are not part of a timeline, there is no user-visible record -of the key verification. +`to_device` messages are not part of a timeline, there is no user-visible +record of the key verification. + +As well, the current key verification framework does not provide any feedback +when interacting with clients that do not support it; if a client does not +support the key verification framework, there is no way for users to discover +this other than waiting for a while and noticing that nothing is happening. + +This proposal will solve both problems. ## Proposal @@ -27,9 +34,27 @@ following properties in its contents: - `body`: a fallback message to alert users that their client does not support the key verification framework, and that they should use a different method - to verify keys + to verify keys. The message should contain Bob's Matrix ID in order to + trigger a notification so that Bob's client will highlight the room for him, + making it easier for him to find it. For example, "@bob:example.com: Alice + is requesting to verify keys with you. However, your client does not support + this method, so you will need to use the legacy method of key verification." + + Clients that do support the key verification framework should hide the body + and instead present the user with an interface to accept or reject the key + verification. + + The event may also contain `format` and `formatted_body` properties as + described in the [m.room.message + msgtypes](https://matrix.org/docs/spec/client_server/r0.5.0#m-room-message-msgtypes) + section of the spec. Clients that support the key verification should + similarly hide these from the user. - `msgtype`: `m.key.verification.request` - `methods`: the verification methods supported by Alice's client +- `to`: Bob's Matrix ID. Users should only respond to verification requests if + they are named in this field. Users who are not named in this field and who + did not send this event should ignore all other events that have a + `m.key.verification` relationship with this event. Key verifications will be identified by the event ID of the key verification request event. @@ -67,7 +92,8 @@ event with the following properties in its contents: - `code`: The error code for why the process/request was cancelled by the user. The contents are the same as the `code` property of the currently defined [`m.key.verification.cancel` to-device - event](https://matrix.org/docs/spec/client_server/r0.5.0#m-key-verification-cancel) + event](https://matrix.org/docs/spec/client_server/r0.5.0#m-key-verification-cancel), + or as defined for specific key verification methods. This message may be sent at any point in the key verification process. Any subsequent key verification messages relating to the same request are ignored. @@ -95,8 +121,32 @@ property, as defined above, is used instead. ## Potential issues +If a user wants to verify their own device, this will require the creation of a +Direct Messaging room with themselves. + +Direct Messaging rooms could have end-to-end encryption enabled, and some +clients can be configured to only send decryption keys to verified devices. +Key verification messages should be granted an exception to this (so that +decryption keys are sent to all of the target user's devices), or should be +sent unencrypted, so that unverified devices will be able to be verified. + +Users might have multiple Direct Messaging rooms with other users. In this +case, clients will need to prompt the user to select the room in which they +want to perform the verification. ## Security considerations +Key verification is subject to the room's visibility settings, and may be +visible to other users in the room. However, key verification does not rely on +secrecy, so this will no affect the security of the key verification. This may +reveal to others in the room that Alice and Bob know each other, but this is +already revealed by the fact that they share a Direct Messaging room. + +This framework allows users to see what key verifications they have performed +in the past. However, since key verification messages are not secured, this +should not be considered as authoritative. ## Conclusion + +By using room messages to perform key verification rather than `to_device` +messages, the user experience of key verification can be improved. From 0007498b4ca47a9640def3dc3ea395ddb34c0cfb Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 5 Sep 2019 11:54:33 -0400 Subject: [PATCH 04/63] remove empty tradeoffs section --- proposals/2241-e2e-verification-in-dms.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/proposals/2241-e2e-verification-in-dms.md b/proposals/2241-e2e-verification-in-dms.md index 8f98ac2e..3663dfef 100644 --- a/proposals/2241-e2e-verification-in-dms.md +++ b/proposals/2241-e2e-verification-in-dms.md @@ -116,9 +116,6 @@ The messages used in SAS verification are the same as those currently defined, except that instead of the `transaction_id` property, an `m.relates_to` property, as defined above, is used instead. -## Tradeoffs - - ## Potential issues If a user wants to verify their own device, this will require the creation of a From e19fca7d54ec6716e6ebce66b19559e86ebcf751 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 25 Sep 2019 15:31:01 -0400 Subject: [PATCH 05/63] make some fixes, add a clarification, add a message to indicate completion --- proposals/2241-e2e-verification-in-dms.md | 29 +++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/proposals/2241-e2e-verification-in-dms.md b/proposals/2241-e2e-verification-in-dms.md index 3663dfef..e21976e9 100644 --- a/proposals/2241-e2e-verification-in-dms.md +++ b/proposals/2241-e2e-verification-in-dms.md @@ -67,7 +67,7 @@ To accept a key verification, Bob will send an `m.key.verification.start` event with the following properties in its contents: - `m.relates_to`: an object with the properties: - - `rel_type`: `m.key.verification` + - `rel_type`: `m.reference` - `event_id`: the event ID of the key verification request that is being accepted - `method`: the key verification method that is being used @@ -85,7 +85,7 @@ To reject a key verification, Bob will send an `m.key.verification.cancel` event with the following properties in its contents: - `m.relates_to`: an object with the properties: - - `rel_type`: `m.key.verification` + - `rel_type`: `m.reference` - `event_id`: the event ID of the key verification that is being cancelled - `body`: A human readable description of the `code`. The client should only rely on this string if it does not understand the `code`. @@ -99,6 +99,20 @@ This message may be sent at any point in the key verification process. Any subsequent key verification messages relating to the same request are ignored. However, this does not undo any verifications that have already been done. +#### Concluding a key verification + +When the other user's key is verified and no more messages are expected, each +party will send an `m.key.verification.done` event with the following +properties in its contents: + +- `m.relates_to`: an object with the properties: + - `rel_type`: `m.reference` + - `event_id`: the event ID of the key verification that is being cancelled + +This provides a record within the room of the result of the verification. + +Any subsequent key verification messages relating to the same request are ignored. + #### Other events Key verification methods may define their own event types, or extensions to the @@ -116,6 +130,17 @@ The messages used in SAS verification are the same as those currently defined, except that instead of the `transaction_id` property, an `m.relates_to` property, as defined above, is used instead. +## Alternatives + +Messages sent by the verification methods, after the initial key verification +request message, could be sent as to-device messages. The +`m.key.verification.start`, `m.key.verification.cancel`, and +`m.key.verification.done` messages must be still be sent in the room, as the +`m.key.verification.start` notifies the sender's other devices that the request +has been acknowledged, and the `m.key.verification.cancel` and +`m.key.verification.done` provide a record of the status of the key +verification. + ## Potential issues If a user wants to verify their own device, this will require the creation of a From 7469198d8b900f8acd8a682182f8134536c1efcc Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 8 Oct 2019 16:19:39 -0400 Subject: [PATCH 06/63] add from_device fields and a FIXME --- proposals/2241-e2e-verification-in-dms.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/proposals/2241-e2e-verification-in-dms.md b/proposals/2241-e2e-verification-in-dms.md index e21976e9..f049540c 100644 --- a/proposals/2241-e2e-verification-in-dms.md +++ b/proposals/2241-e2e-verification-in-dms.md @@ -55,6 +55,8 @@ following properties in its contents: they are named in this field. Users who are not named in this field and who did not send this event should ignore all other events that have a `m.key.verification` relationship with this event. +- `from_device`: Alice's device ID. This is required since some verification + methods may use the device IDs as part of the verification process. Key verifications will be identified by the event ID of the key verification request event. @@ -66,11 +68,16 @@ Clients should ignore verification requests that have been accepted or cancelled To accept a key verification, Bob will send an `m.key.verification.start` event with the following properties in its contents: +TODO: MSC1849 may use `m.relationship` rather than `m.relates_to`, in which +case this proposal should follow suit. + - `m.relates_to`: an object with the properties: - `rel_type`: `m.reference` - `event_id`: the event ID of the key verification request that is being accepted - `method`: the key verification method that is being used +- `from_device`: Bob's device ID. This is required since some verification + methods may use the device IDs as part of the verification process. Clients should ignore `m.key.verification.start` events that correspond to verification requests that it did not send. From ab3ed738e4b49fec76f0aecca4b210bc7afe57f2 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 8 Oct 2019 16:27:53 -0400 Subject: [PATCH 07/63] drop the recommendation that requests highlight the user --- proposals/2241-e2e-verification-in-dms.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/proposals/2241-e2e-verification-in-dms.md b/proposals/2241-e2e-verification-in-dms.md index f049540c..9d53a290 100644 --- a/proposals/2241-e2e-verification-in-dms.md +++ b/proposals/2241-e2e-verification-in-dms.md @@ -34,11 +34,9 @@ following properties in its contents: - `body`: a fallback message to alert users that their client does not support the key verification framework, and that they should use a different method - to verify keys. The message should contain Bob's Matrix ID in order to - trigger a notification so that Bob's client will highlight the room for him, - making it easier for him to find it. For example, "@bob:example.com: Alice - is requesting to verify keys with you. However, your client does not support - this method, so you will need to use the legacy method of key verification." + to verify keys. For example, "Alice is requesting to verify keys with you. + However, your client does not support this method, so you will need to use + the legacy method of key verification." Clients that do support the key verification framework should hide the body and instead present the user with an interface to accept or reject the key From 1f1d22f66706e77026920ea2936f663d2cdb9d8e Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 8 Oct 2019 16:46:15 -0400 Subject: [PATCH 08/63] fix a couple of missed m.reference changes --- proposals/2241-e2e-verification-in-dms.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/2241-e2e-verification-in-dms.md b/proposals/2241-e2e-verification-in-dms.md index 9d53a290..ea813fdb 100644 --- a/proposals/2241-e2e-verification-in-dms.md +++ b/proposals/2241-e2e-verification-in-dms.md @@ -52,7 +52,7 @@ following properties in its contents: - `to`: Bob's Matrix ID. Users should only respond to verification requests if they are named in this field. Users who are not named in this field and who did not send this event should ignore all other events that have a - `m.key.verification` relationship with this event. + `m.reference` relationship with this event. - `from_device`: Alice's device ID. This is required since some verification methods may use the device IDs as part of the verification process. @@ -126,7 +126,7 @@ should have an `m.relates_to` property as defined for `m.key.verification.accept` or `m.key.verification.cancel` events. Clients should ignore events with an `m.relates_to` that have a `rel_type` of -`m.key.verification` that refer to a verification where it is not the requester +`m.reference` that refer to a verification where it is not the requester nor the accepter. ### SAS verification From 06ee66d6b08b3162ca94df38f9b82b5e4a49860e Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 23 Oct 2019 15:30:07 +0100 Subject: [PATCH 09/63] Apply suggestions from code review Co-Authored-By: Kitsune Ral Co-Authored-By: David Baker --- proposals/2241-e2e-verification-in-dms.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/2241-e2e-verification-in-dms.md b/proposals/2241-e2e-verification-in-dms.md index ea813fdb..eccc36c2 100644 --- a/proposals/2241-e2e-verification-in-dms.md +++ b/proposals/2241-e2e-verification-in-dms.md @@ -78,9 +78,9 @@ case this proposal should follow suit. methods may use the device IDs as part of the verification process. Clients should ignore `m.key.verification.start` events that correspond to -verification requests that it did not send. +verification requests that they did not send. -Clients may use this event as a place in the room's timeline do display +Clients may use this event as a place in the room's timeline to display progress of the key verification process and to interact with the user as necessary. @@ -129,7 +129,7 @@ Clients should ignore events with an `m.relates_to` that have a `rel_type` of `m.reference` that refer to a verification where it is not the requester nor the accepter. -### SAS verification +### SAS verification The messages used in SAS verification are the same as those currently defined, except that instead of the `transaction_id` property, an `m.relates_to` From 1d165eec2968ede8f6731c040ba9484fe6a06300 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 23 Oct 2019 13:22:10 -0400 Subject: [PATCH 10/63] add clarifications --- proposals/2241-e2e-verification-in-dms.md | 25 ++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/proposals/2241-e2e-verification-in-dms.md b/proposals/2241-e2e-verification-in-dms.md index ea813fdb..6e1976cf 100644 --- a/proposals/2241-e2e-verification-in-dms.md +++ b/proposals/2241-e2e-verification-in-dms.md @@ -59,7 +59,26 @@ following properties in its contents: Key verifications will be identified by the event ID of the key verification request event. -Clients should ignore verification requests that have been accepted or cancelled. +Clients should ignore verification requests that have been accepted or +cancelled, or if they do not belong to the sending or target users. + +The way that clients display this event can depend on which user and device the +client belongs to, and what state the verification is in. For example: + +- If the verification has been completed (there is an `m.key.verification.done` + or `m.key.verification.cancel` event), the client can indicate that the + verification was successful or had an error. +- If the verification has been accepted (there is an `m.key.verification.start` + event) but has not been completed, the two devices involved can indicate that + the verification is in progress and can use this event as a place in the + room's timeline to display progress of the key verification and to interact + with the user as necessary. Other devices can indicate that the verification + is in progress on other devices. +- If the verification has not been accepted, clients for the target user can + indicate that a verification has been requested and allow the user to accept + the verification on that device. The sending client can indicate that it is + waiting for the request to be accepted, and the sending user's other clients + can indicate the that a request was initiated on a different device. #### Accepting a key verification @@ -80,10 +99,6 @@ case this proposal should follow suit. Clients should ignore `m.key.verification.start` events that correspond to verification requests that it did not send. -Clients may use this event as a place in the room's timeline do display -progress of the key verification process and to interact with the user as -necessary. - #### Rejecting a key verification To reject a key verification, Bob will send an `m.key.verification.cancel` From 746695574458feda6022c95ed464a6d8d637cb26 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 1 Nov 2019 14:54:58 -0400 Subject: [PATCH 11/63] add note that verifying yourself may want to use to_device instead --- proposals/2241-e2e-verification-in-dms.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/2241-e2e-verification-in-dms.md b/proposals/2241-e2e-verification-in-dms.md index fbfbe62e..77340c5b 100644 --- a/proposals/2241-e2e-verification-in-dms.md +++ b/proposals/2241-e2e-verification-in-dms.md @@ -164,7 +164,8 @@ verification. ## Potential issues If a user wants to verify their own device, this will require the creation of a -Direct Messaging room with themselves. +Direct Messaging room with themselves. Instead, clients may use the current +`to_device` messages for verifying the user's other devices. Direct Messaging rooms could have end-to-end encryption enabled, and some clients can be configured to only send decryption keys to verified devices. From f4bad37c10f6817d557b1cb5b381493d1351823f Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 5 Nov 2019 16:20:41 -0500 Subject: [PATCH 12/63] add notes about redactions/edits --- proposals/2241-e2e-verification-in-dms.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/proposals/2241-e2e-verification-in-dms.md b/proposals/2241-e2e-verification-in-dms.md index 77340c5b..a29d7703 100644 --- a/proposals/2241-e2e-verification-in-dms.md +++ b/proposals/2241-e2e-verification-in-dms.md @@ -144,6 +144,11 @@ Clients should ignore events with an `m.relates_to` that have a `rel_type` of `m.reference` that refer to a verification where it is not the requester nor the accepter. +Clients should not redact or edit verification messages. A client may ignore +redactions or edits of key verification messages, or may cancel the +verification with a `code` of `m.unexpected_message` when it receives a +redaction or edit. + ### SAS verification The messages used in SAS verification are the same as those currently defined, From a514485bcb733fb58847872a2ed81723c015b224 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 5 Nov 2019 16:22:45 -0500 Subject: [PATCH 13/63] add note about displaying other events --- proposals/2241-e2e-verification-in-dms.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/proposals/2241-e2e-verification-in-dms.md b/proposals/2241-e2e-verification-in-dms.md index a29d7703..e3d7239f 100644 --- a/proposals/2241-e2e-verification-in-dms.md +++ b/proposals/2241-e2e-verification-in-dms.md @@ -80,6 +80,10 @@ client belongs to, and what state the verification is in. For example: waiting for the request to be accepted, and the sending user's other clients can indicate the that a request was initiated on a different device. +Clients may choose to display or not to display events of any other type that +reference the original request event; but it must not have any effect on the +verification itself. + #### Accepting a key verification To accept a key verification, Bob will send an `m.key.verification.start` event From 1590ae224c476d90cdc14bee9c0a632768ecb9f6 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 18 Nov 2019 16:24:59 -0500 Subject: [PATCH 14/63] make hash commitment always include the m.relates_to --- proposals/2241-e2e-verification-in-dms.md | 79 +++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/proposals/2241-e2e-verification-in-dms.md b/proposals/2241-e2e-verification-in-dms.md index e3d7239f..50e16c32 100644 --- a/proposals/2241-e2e-verification-in-dms.md +++ b/proposals/2241-e2e-verification-in-dms.md @@ -159,6 +159,85 @@ The messages used in SAS verification are the same as those currently defined, except that instead of the `transaction_id` property, an `m.relates_to` property, as defined above, is used instead. +If the key verification messages are encrypted, the hash commitment sent in the +`m.key.verification.accept` message MUST be based on the decrypted +`m.key.verification.start` message contents, and include the `m.relates_to` +field, even if the decrypted message contents do not include that field. For +example, if Alice sends a message to start the SAS verification: + +```json +{ + "content": { + "algorithm": "m.megolm.v1.aes-sha2", + "ciphertext": "ABCDEFG...", + "device_id": "Dynabook", + "sender_key": "alice+sender+key", + "session_id": "session+id", + "m.relates_to": { + "rel_type": "m.reference", + "event_id": "$verification_request_event" + } + }, + "event_id": "$event_id", + "origin_server_ts": 1234567890, + "sender": "@alice:example.org", + "type": "m.room.encrypted", + "room_id": "!room_id:example.org" +} +``` + +which, when decrypted, yields: + +```json +{ + "room_id": "!room_id:example.org", + "type": "m.key.verification.start", + "content": { + "from_device": "Dynabook", + "hashes": [ + "sha256" + ], + "key_agreement_protocols": [ + "curve25519" + ], + "message_authentication_codes": [ + "hkdf-hmac-sha256" + ], + "method": "m.sas.v1", + "short_authentication_string": [ + "decimal", + "emoji" + ] + } +} +``` + +then the hash commitment will be based on the message contents: + +```json +{ + "from_device": "Dynabook", + "hashes": [ + "sha256" + ], + "key_agreement_protocols": [ + "curve25519" + ], + "message_authentication_codes": [ + "hkdf-hmac-sha256" + ], + "method": "m.sas.v1", + "short_authentication_string": [ + "decimal", + "emoji" + ], + "m.relates_to": { + "rel_type": "m.reference", + "event_id": "$verification_request_event" + } +} +``` + ## Alternatives Messages sent by the verification methods, after the initial key verification From 91f51bb23e30d511a274f5b05504a6ee69583d10 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 15 Apr 2020 16:09:36 -0400 Subject: [PATCH 15/63] use .ready to accept a verification, plus some clarification --- proposals/2241-e2e-verification-in-dms.md | 52 ++++++++++++++++++----- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/proposals/2241-e2e-verification-in-dms.md b/proposals/2241-e2e-verification-in-dms.md index 50e16c32..90fa59fc 100644 --- a/proposals/2241-e2e-verification-in-dms.md +++ b/proposals/2241-e2e-verification-in-dms.md @@ -86,7 +86,7 @@ verification itself. #### Accepting a key verification -To accept a key verification, Bob will send an `m.key.verification.start` event +To accept a key verification, Bob will send an `m.key.verification.ready` event with the following properties in its contents: TODO: MSC1849 may use `m.relationship` rather than `m.relates_to`, in which @@ -96,17 +96,38 @@ case this proposal should follow suit. - `rel_type`: `m.reference` - `event_id`: the event ID of the key verification request that is being accepted -- `method`: the key verification method that is being used +- `methods`: an array of verification methods that the device supports - `from_device`: Bob's device ID. This is required since some verification methods may use the device IDs as part of the verification process. -Clients should ignore `m.key.verification.start` events that correspond to +Clients should ignore `m.key.verification.ready` events that correspond to verification requests that they did not send. +After this, either Alice or Bob may start the verification by sending an +`m.key.verification.start` event with the following properties in its contents: + +- `m.relates_to`: an object with the properties: + - `rel_type`: `m.reference` + - `event_id`: the event ID of the key verification request that is being + started +- `method`: the key verification method that is being used. This should be a + method that both Alice's and Bob's devices support. +- `from_device`: The user's device ID. + +If both Alice and Bob send an `m.key.verification.start` message, and they both +specify the same verification method, then the event sent by the user whose +user ID is the smallest is used, and the other event is ignored. If they both +send an `m.key.verification.start` message and the method is different, then +the verification should be cancelled with a `code` of `m.unexpected_message`. + +After the `m.key.verification.start` event is sent, the devices may exchange +messages (if any) according to the verification method in use. + #### Rejecting a key verification -To reject a key verification, Bob will send an `m.key.verification.cancel` -event with the following properties in its contents: +To reject a key verification, Alice or Bob will send an +`m.key.verification.cancel` event with the following properties in its +contents: - `m.relates_to`: an object with the properties: - `rel_type`: `m.reference` @@ -135,7 +156,13 @@ properties in its contents: This provides a record within the room of the result of the verification. -Any subsequent key verification messages relating to the same request are ignored. +Any subsequent key verification messages relating to the same request are +ignored. + +Although a client may have successfully completed its side of the verification, +it may wait until receiving an `m.key.verification.done` (or +`m.key.verification.cancel`) event from the other device before informing the +user that the verification was successful or unsuccessful. #### Other events @@ -145,7 +172,7 @@ should have an `m.relates_to` property as defined for `m.key.verification.accept` or `m.key.verification.cancel` events. Clients should ignore events with an `m.relates_to` that have a `rel_type` of -`m.reference` that refer to a verification where it is not the requester +`m.reference` that refer to a verification where it is neither the requester nor the accepter. Clients should not redact or edit verification messages. A client may ignore @@ -242,13 +269,16 @@ then the hash commitment will be based on the message contents: Messages sent by the verification methods, after the initial key verification request message, could be sent as to-device messages. The -`m.key.verification.start`, `m.key.verification.cancel`, and +`m.key.verification.ready`, `m.key.verification.cancel`, and `m.key.verification.done` messages must be still be sent in the room, as the -`m.key.verification.start` notifies the sender's other devices that the request +`m.key.verification.ready` notifies the sender's other devices that the request has been acknowledged, and the `m.key.verification.cancel` and `m.key.verification.done` provide a record of the status of the key verification. +However, it seems more natural to have all messages sent via the same +mechanism. + ## Potential issues If a user wants to verify their own device, this will require the creation of a @@ -262,8 +292,8 @@ decryption keys are sent to all of the target user's devices), or should be sent unencrypted, so that unverified devices will be able to be verified. Users might have multiple Direct Messaging rooms with other users. In this -case, clients will need to prompt the user to select the room in which they -want to perform the verification. +case, clients could need to prompt the user to select the room in which they +want to perform the verification, or could select a room. ## Security considerations From 1be21b85b6bfed09a8fa7a78f735f9fabbc7a0e2 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 30 Jul 2020 10:57:18 -0600 Subject: [PATCH 16/63] Proposal to remove deprecated identity service endpoints --- ...00-remove-deprecated-identity-endpoints.md | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 proposals/0000-remove-deprecated-identity-endpoints.md diff --git a/proposals/0000-remove-deprecated-identity-endpoints.md b/proposals/0000-remove-deprecated-identity-endpoints.md new file mode 100644 index 00000000..7fda56a6 --- /dev/null +++ b/proposals/0000-remove-deprecated-identity-endpoints.md @@ -0,0 +1,26 @@ +# MSC0000: Remove deprecated Identity Service endpoints + +Implementations will have had plenty of time to adopt the new v2 API for Identity Servers, so +we should clean out the old endpoints. + +All deprecated endpoints in the r0.3.0 Identity Service API specification are to be removed. + +For completeness, this includes: + +* `GET /_matrix/identity/api/v1` +* `GET /_matrix/identity/api/v1/pubkey/{keyId}` +* `GET /_matrix/identity/api/v1/pubkey/isvalid` +* `GET /_matrix/identity/api/v1/pubkey/ephemeral/isvalid` +* `GET /_matrix/identity/api/v1/lookup` +* `POST /_matrix/identity/api/v1/bulk_lookup` +* `POST /_matrix/identity/api/v1/validate/email/requestToken` +* `POST /_matrix/identity/api/v1/validate/email/submitToken` +* `GET /_matrix/identity/api/v1/validate/email/submitToken` +* `POST /_matrix/identity/api/v1/validate/msisdn/requestToken` +* `POST /_matrix/identity/api/v1/validate/msisdn/submitToken` +* `GET /_matrix/identity/api/v1/validate/msisdn/submitToken` +* `GET /_matrix/identity/api/v1/3pid/getValidated3pid` +* `POST /_matrix/identity/api/v1/3pid/bind` +* `POST /_matrix/identity/api/v1/3pid/unbind` +* `POST /_matrix/identity/api/v1/store-invite` +* `POST /_matrix/identity/api/v1/sign-ed25519` From 65c6d545b84c5d8d8eefd3eecfe0b361d84b2a31 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 30 Jul 2020 10:59:00 -0600 Subject: [PATCH 17/63] assign number --- ...ndpoints.md => 2713-remove-deprecated-identity-endpoints.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename proposals/{0000-remove-deprecated-identity-endpoints.md => 2713-remove-deprecated-identity-endpoints.md} (95%) diff --git a/proposals/0000-remove-deprecated-identity-endpoints.md b/proposals/2713-remove-deprecated-identity-endpoints.md similarity index 95% rename from proposals/0000-remove-deprecated-identity-endpoints.md rename to proposals/2713-remove-deprecated-identity-endpoints.md index 7fda56a6..6e49477d 100644 --- a/proposals/0000-remove-deprecated-identity-endpoints.md +++ b/proposals/2713-remove-deprecated-identity-endpoints.md @@ -1,4 +1,4 @@ -# MSC0000: Remove deprecated Identity Service endpoints +# MSC2713: Remove deprecated Identity Service endpoints Implementations will have had plenty of time to adopt the new v2 API for Identity Servers, so we should clean out the old endpoints. From 4a779784efce85a31df7f7c7b56fae0c0299ab13 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Sun, 6 Dec 2020 09:43:53 -0500 Subject: [PATCH 18/63] Update proposals/2241-e2e-verification-in-dms.md Co-authored-by: poljar --- proposals/2241-e2e-verification-in-dms.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2241-e2e-verification-in-dms.md b/proposals/2241-e2e-verification-in-dms.md index 90fa59fc..f8d9ac97 100644 --- a/proposals/2241-e2e-verification-in-dms.md +++ b/proposals/2241-e2e-verification-in-dms.md @@ -152,7 +152,7 @@ properties in its contents: - `m.relates_to`: an object with the properties: - `rel_type`: `m.reference` - - `event_id`: the event ID of the key verification that is being cancelled + - `event_id`: the event ID of the key verification that is being concluded This provides a record within the room of the result of the verification. From affa240543c94a275685191465bd8ce9be68b25f Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 14 Dec 2020 11:33:33 -0500 Subject: [PATCH 19/63] use `reason` for human-readable cancel reason for consistency with non-DM version --- proposals/2241-e2e-verification-in-dms.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2241-e2e-verification-in-dms.md b/proposals/2241-e2e-verification-in-dms.md index f8d9ac97..46f303c2 100644 --- a/proposals/2241-e2e-verification-in-dms.md +++ b/proposals/2241-e2e-verification-in-dms.md @@ -132,7 +132,7 @@ contents: - `m.relates_to`: an object with the properties: - `rel_type`: `m.reference` - `event_id`: the event ID of the key verification that is being cancelled -- `body`: A human readable description of the `code`. The client should only +- `reason`: A human readable description of the `code`. The client should only rely on this string if it does not understand the `code`. - `code`: The error code for why the process/request was cancelled by the user. The contents are the same as the `code` property of the currently From 609641636dcd9fa3008f3a815af10886410443c9 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 13 Apr 2021 12:29:58 -0400 Subject: [PATCH 20/63] decouple from MSC1849/MSC2674 --- proposals/2241-e2e-verification-in-dms.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/proposals/2241-e2e-verification-in-dms.md b/proposals/2241-e2e-verification-in-dms.md index 46f303c2..dc2797f2 100644 --- a/proposals/2241-e2e-verification-in-dms.md +++ b/proposals/2241-e2e-verification-in-dms.md @@ -89,9 +89,6 @@ verification itself. To accept a key verification, Bob will send an `m.key.verification.ready` event with the following properties in its contents: -TODO: MSC1849 may use `m.relationship` rather than `m.relates_to`, in which -case this proposal should follow suit. - - `m.relates_to`: an object with the properties: - `rel_type`: `m.reference` - `event_id`: the event ID of the key verification request that is being @@ -100,6 +97,10 @@ case this proposal should follow suit. - `from_device`: Bob's device ID. This is required since some verification methods may use the device IDs as part of the verification process. +(Note: the form of the `m.relates_to` property is based on the current state of +[MSC2674](https://github.com/matrix-org/matrix-doc/pull/2674), but is +independent from it since this MSC does not rely on any aggregations features.) + Clients should ignore `m.key.verification.ready` events that correspond to verification requests that they did not send. From 62896cdea9ce20ab3946eaa734a6cdcb5c1ffd1e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 6 Apr 2021 09:02:24 -0600 Subject: [PATCH 21/63] Apply suggestions from code review Co-authored-by: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> --- CONTRIBUTING.rst | 2 +- README.md | 10 +++++----- meta/documentation_style.rst | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index b9c66805..e3db28fd 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -103,7 +103,7 @@ the ``newsfragments`` directory. The ``type`` can be one of the following: All news fragments must have a brief summary explaining the change in the contents of the file. The summary must end in a full stop to be in line with -the style guide and and formatting must be done using Markdown. +the style guide and formatting must be done using Markdown. Changes that do not change the spec, such as changes to the build script, formatting, CSS, etc should not get a news fragment. diff --git a/README.md b/README.md index 009b94e6..838a5365 100644 --- a/README.md +++ b/README.md @@ -35,8 +35,8 @@ The Matrix spec is compiled with [Hugo](https://gohugo.io/) (a static site gener * `/themes`: you can use just Hugo or use it with a theme. Themes primarily provide additional templates, which are supplied in a `/themes/$theme_name/layouts` directory. You can use a theme but customise it by providing your own - versions of any of the them layouts in the base `/layouts` directory. That is, if a theme provides - `/themes/$theme_name/layouts/sidebar.html` and you provide `/layouts/sidebar.html`, then your version of this + versions of any of the theme layouts in the base `/layouts` directory. That is, if a theme provides + `/themes/$theme_name/layouts/sidebar.html` and you provide `/layouts/sidebar.html`, then your version of the template will be used. It also has the following top-level file: @@ -51,7 +51,7 @@ Additionally, the following directories may be of interest: * `/event-schemas`: [JSON Schema](http://json-schema.org/) definitions for the spec. * `/data-definitions`: Bits of structured data consumable by Matrix implementations. * `/meta`: Documentation relating to the spec's processes that are otherwise untracked (release instructions, etc). -* `/scripts`: Various scripts for generating the spec. +* `/scripts`: Various scripts for generating the spec and validating its contents. * `/proposals`: Matrix Spec Change (MSC) proposals. See . ## Authoring changes to the spec @@ -62,7 +62,7 @@ place after an MSC has been accepted, not as part of a proposal itself. 1. Install the extended version (often the OS default) of Hugo: 2. Run `git submodule update --init --recursive` for good measure. 3. Run `npm i` to install the dependencies. Note that this will require NodeJS to be installed. -4. Run `npm run get-proposals` to seed the proposals data. This is not required. +4. Run `npm run get-proposals` to seed proposal data. This is merely for populating the content of the "Spec Change Proposals" page and is not required. 5. Run `hugo serve` to run a local webserver which builds whenever a file change is detected. If watching doesn't appear to be working for you, try `hugo serve --disableFastRender` instead. 6. Edit the specification 🙂 @@ -73,7 +73,7 @@ Awesome. If you're looking at making design-related changes to the spec site, pl ## Building the specification -If for some reason you're not a CI/CD system and want to render the spec yourself, follow the above steps for authoring +If for some reason you're not a CI/CD system and want to render a static version of the spec for yourself, follow the above steps for authoring changes to the specification and instead of `hugo serve` run `hugo -d "spec"` - this will generate the spec to `/spec`. If you'd like to serve the spec off a path instead of a domain root (eg: `/unstable`), add `--baseURL "/unstable"` to the `hugo -d "spec"` command. diff --git a/meta/documentation_style.rst b/meta/documentation_style.rst index 5528f73e..cfec5e3b 100644 --- a/meta/documentation_style.rst +++ b/meta/documentation_style.rst @@ -8,7 +8,7 @@ in. Format ------ -Documentation is written either in github-flavored markdown. +Documentation is written in github-flavored markdown. Sections -------- From b455fc73f1ca67e8a5da498672589580a36ae7a2 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 6 Apr 2021 09:42:33 -0600 Subject: [PATCH 22/63] Reference drafts properly --- scripts/speculator/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/speculator/main.go b/scripts/speculator/main.go index 12ec2aec..e09846a8 100644 --- a/scripts/speculator/main.go +++ b/scripts/speculator/main.go @@ -337,7 +337,7 @@ func (s *server) serveSpec(w http.ResponseWriter, req *http.Request) { log.Printf("Serving pr %s (%s)\n", branchName, sha) } else if strings.ToLower(branchName) == "head" || branchName == "master" || - strings.HasPrefix(branchName, "drafts/") { + strings.HasPrefix(branchName, "attic/drafts/") { branchSHA, err := s.lookupBranch(branchName) if err != nil { writeError(w, 400, err) From b518e4ade0a0c0149f9c3116ce075863a0466141 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 6 Apr 2021 09:43:05 -0600 Subject: [PATCH 23/63] Finish sentence --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 838a5365..ad98da40 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ The Matrix spec is compiled with [Hugo](https://gohugo.io/) (a static site gener * `/data`: this can contain TOML, YAML, or JSON files. Files kept here are directly available to template code as [data objects](https://gohugo.io/templates/data-templates/), so templates don't need to load them from a file and - parse them. This is also where our + parse them. This is also where our Swagger/OpenAPI definitions are. * `/layouts`: this contains [Hugo templates](https://gohugo.io/templates/). Some templates define the overall layout of a page: for example, whether it has header, footer, sidebar, and so on. From a2280c7815ad0d4a7322ee83e4cf609fa7af2ddc Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 6 Apr 2021 09:43:38 -0600 Subject: [PATCH 24/63] s --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ad98da40..3f85920d 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,10 @@ This repository contains the Matrix Specification, rendered at [spec.matrix.org](http://spec.matrix.org/). -Developers looking to use Matrix should join [#matrix-dev:matrix.org](http://matrix.to/#/#matrix-dev:matrix.org) +Developers looking to use Matrix should join [#matrix-dev:matrix.org](https://matrix.to/#/#matrix-dev:matrix.org) on Matrix for help. -Spec authors and proposal writers are welcome to join [#matrix-spec:matrix.org](http://matrix.to/#/#matrix-spec:matrix.org). We welcome contributions! See [CONTRIBUTING.rst](./CONTRIBUTING.rst) for details. +Spec authors and proposal writers are welcome to join [#matrix-spec:matrix.org](https://matrix.to/#/#matrix-spec:matrix.org). We welcome contributions! See [CONTRIBUTING.rst](./CONTRIBUTING.rst) for details. ## Structure From 7e6ab07f96b2ca9924069f116fad117db220abf0 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 6 Apr 2021 09:44:56 -0600 Subject: [PATCH 25/63] Line length and words --- README.md | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 3f85920d..bfcfd87d 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,8 @@ This repository contains the Matrix Specification, rendered at [spec.matrix.org] Developers looking to use Matrix should join [#matrix-dev:matrix.org](https://matrix.to/#/#matrix-dev:matrix.org) on Matrix for help. -Spec authors and proposal writers are welcome to join [#matrix-spec:matrix.org](https://matrix.to/#/#matrix-spec:matrix.org). We welcome contributions! See [CONTRIBUTING.rst](./CONTRIBUTING.rst) for details. +Spec authors and proposal writers are welcome to join [#matrix-spec:matrix.org](https://matrix.to/#/#matrix-spec:matrix.org). +We welcome contributions! See [CONTRIBUTING.rst](./CONTRIBUTING.rst) for details. ## Structure @@ -62,7 +63,8 @@ place after an MSC has been accepted, not as part of a proposal itself. 1. Install the extended version (often the OS default) of Hugo: 2. Run `git submodule update --init --recursive` for good measure. 3. Run `npm i` to install the dependencies. Note that this will require NodeJS to be installed. -4. Run `npm run get-proposals` to seed proposal data. This is merely for populating the content of the "Spec Change Proposals" page and is not required. +4. Run `npm run get-proposals` to seed proposal data. This is merely for populating the content of the "Spec Change Proposals" + page and is not required. 5. Run `hugo serve` to run a local webserver which builds whenever a file change is detected. If watching doesn't appear to be working for you, try `hugo serve --disableFastRender` instead. 6. Edit the specification 🙂 @@ -73,18 +75,18 @@ Awesome. If you're looking at making design-related changes to the spec site, pl ## Building the specification -If for some reason you're not a CI/CD system and want to render a static version of the spec for yourself, follow the above steps for authoring -changes to the specification and instead of `hugo serve` run `hugo -d "spec"` - this will generate the spec to `/spec`. -If you'd like to serve the spec off a path instead of a domain root (eg: `/unstable`), add `--baseURL "/unstable"` to -the `hugo -d "spec"` command. +If for some reason you're not a CI/CD system and want to render a static version of the spec for yourself, follow the above +steps for authoring changes to the specification and instead of `hugo serve` run `hugo -d "spec"` - this will generate the +spec to `/spec`. If you'd like to serve the spec off a path instead of a domain root (eg: `/unstable`), add `--baseURL "/unstable"` +to the `hugo -d "spec"` command. -For building the swagger definitions, create a python3 virtualenv and activate it. Then run `pip install -r ./scripts/requirements.txt` and finally `python ./scripts/dump-swagger.py` to generate it to `./scripts/swagger/api-docs.json`. -To make use of the generated file, there are a number of options: +For building the swagger definitions, create a python3 virtualenv and activate it. Then run `pip install -r ./scripts/requirements.txt` +and finally `python ./scripts/dump-swagger.py` to generate it to `./scripts/swagger/api-docs.json`. To make use of the generated file, +there are a number of options: -* It can be uploaded from your filesystem to an online editor/viewer such as - http://editor.swagger.io/ +* It can be uploaded from your filesystem to an online editor/viewer such as [on the swagger website](http://editor.swagger.io/). * You can run a local HTTP server by running `./scripts/swagger-http-server.py`, and then view the documentation via an - online viewer; for example, at + online viewer; for example, at . * You can host the swagger UI yourself. See for advice on how to do so. From 228fcb8175c41311c46556495bf0655952001584 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 5 Apr 2021 20:23:15 -0600 Subject: [PATCH 26/63] Allow
and in suggested HTML subset Specs [MSC2184](https://github.com/matrix-org/matrix-doc/pull/2184) Based on https://github.com/matrix-org/matrix-doc/pull/3094 --- content/client-server-api/modules/instant_messaging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/client-server-api/modules/instant_messaging.md b/content/client-server-api/modules/instant_messaging.md index 8e6df01d..3a933a93 100644 --- a/content/client-server-api/modules/instant_messaging.md +++ b/content/client-server-api/modules/instant_messaging.md @@ -53,7 +53,7 @@ tags to permit, denying the use and rendering of anything else, is: `font`, `del`, `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `blockquote`, `p`, `a`, `ul`, `ol`, `sup`, `sub`, `li`, `b`, `i`, `u`, `strong`, `em`, `strike`, `code`, `hr`, `br`, `div`, `table`, `thead`, `tbody`, `tr`, -`th`, `td`, `caption`, `pre`, `span`, `img`. +`th`, `td`, `caption`, `pre`, `span`, `img`, `details`, `summary`. Not all attributes on those tags should be permitted as they may be avenues for other disruption attempts, such as adding `onclick` handlers From 2603ea6339f5041cfddfe58b611e43a1b6175e14 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 6 Apr 2021 09:45:23 -0600 Subject: [PATCH 27/63] goodbye legacy config --- pyproject.toml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 17a9e62d..19a6ee8b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,9 +1,5 @@ [ tool.gilesbot ] - [ tool.gilesbot.circleci_artifacts.legacydocs ] - url = "gen/index.html" - message = "Click details to preview the legacy HTML documentation." - [ tool.gilesbot.circleci_artifacts.docs ] url = "public/index.html" message = "Click details to preview the HTML documentation." From 30f37f1e669308d1f648ae40c2a942fbbd30507f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 5 Apr 2021 20:18:46 -0600 Subject: [PATCH 28/63] Sprinkle some DANGER: UNSAFE warnings over the spec about event bodies Specs [MSC2801](https://github.com/matrix-org/matrix-doc/pull/2801) Based on https://github.com/matrix-org/matrix-doc/pull/3094 --- content/_index.md | 12 ++++++++++++ content/client-server-api/_index.md | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/content/_index.md b/content/_index.md index 0b82c74a..d28d5c4b 100644 --- a/content/_index.md +++ b/content/_index.md @@ -232,6 +232,18 @@ reserved for events defined in the Matrix specification - for instance `m.room.message` is the event type for instant messages. Events are usually sent in the context of a "Room". +{{% boxes/warning %}} +Event bodies are considered untrusted data. This means that anyone using +Matrix must validate that the event body is of the expected shape/schema +before using the contents verbatim. + +**It is not safe to assume that an event body will have all the expected +fields of the expected types.** + +See [MSC2801](https://github.com/matrix-org/matrix-doc/pull/2801) for more +detail on why this assumption is unsafe. +{{% /boxes/warning %}} + ### Event Graphs Events exchanged in the context of a room are stored in a directed diff --git a/content/client-server-api/_index.md b/content/client-server-api/_index.md index 06d161be..adace4f0 100644 --- a/content/client-server-api/_index.md +++ b/content/client-server-api/_index.md @@ -1381,6 +1381,18 @@ opaque string. No changes should be required to support the currently available room versions. {{% /boxes/warning %}} +{{% boxes/warning %}} +Event bodies are considered untrusted data. This means that anyone using +Matrix must validate that the event body is of the expected shape/schema +before using the contents verbatim. + +**It is not safe to assume that an event body will have all the expected +fields of the expected types.** + +See [MSC2801](https://github.com/matrix-org/matrix-doc/pull/2801) for more +detail on why this assumption is unsafe. +{{% /boxes/warning %}} + ### Types of room events Room events are split into two categories: From a0345ea0bb0a3b19b97136017ac782b6056a6c0f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 5 Apr 2021 20:07:07 -0600 Subject: [PATCH 29/63] Incorporate spoilers and `color` tag allowance Specs [MSC2010](https://github.com/matrix-org/matrix-doc/pull/2010) Specs [MSC2557](https://github.com/matrix-org/matrix-doc/pull/2557) Specs [MSC2422](https://github.com/matrix-org/matrix-doc/pull/2422) Obsoletes https://github.com/matrix-org/matrix-doc/pull/2549 Built upon https://github.com/matrix-org/matrix-doc/pull/3094 --- .../modules/instant_messaging.md | 51 ++++++++++++++++++- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/content/client-server-api/modules/instant_messaging.md b/content/client-server-api/modules/instant_messaging.md index 8e6df01d..8929ce67 100644 --- a/content/client-server-api/modules/instant_messaging.md +++ b/content/client-server-api/modules/instant_messaging.md @@ -63,10 +63,11 @@ are listed, clients should translate the value (a 6-character hex color code) to the appropriate CSS/attributes for the tag. `font` -`data-mx-bg-color`, `data-mx-color` +`data-mx-bg-color`, `data-mx-color`, `color` `span` -`data-mx-bg-color`, `data-mx-color` +`data-mx-bg-color`, `data-mx-color`, `data-mx-spoiler` (see +[spoiler messages](#spoiler-messages)) `a` `name`, `target`, `href` (provided the value is not relative and has a @@ -461,6 +462,52 @@ For `m.image`, the text should be `"sent an image."`. For `m.video`, the text should be `"sent a video."`. For `m.audio`, the text should be `"sent an audio file"`. +##### Spoiler messages + +Parts of a message can be hidden visually from the user through use of spoilers. +This does not affect the server's representation of the event content - it +is simply a visual cue to the user that the message may reveal important +information about something, spoiling any relevant surprise. + +To send spoilers clients MUST use the `formatted_body` and therefore the +`org.matrix.custom.html` format, described above. This makes spoilers valid on +any `msgtype` which can support this format appropriately. + +Spoilers themselves are contained with `span` tags, with the reason (optionally) +being in the `data-mx-spoiler` attribute. Spoilers without a reason must at least +specify the attribute, though the value may be empty/undefined. + +An example of a spoiler is: + +```json +{ + "msgtype": "m.text", + "format": "org.matrix.custom.html", + "body": "Alice [Spoiler](mxc://example.org/abc123) in the movie.", + "formatted_body": "Alice lived happily ever after in the movie." +} +``` + +If a reason were to be supplied, it would look like: + +```json +{ + "msgtype": "m.text", + "format": "org.matrix.custom.html", + "body": "Alice [Spoiler for health of Alice](mxc://example.org/abc123) in the movie.", + "formatted_body": "Alice lived happily ever after in the movie." +} +``` + +When sending a spoiler, clients SHOULD provide the plain text fallback in the `body` +as shown above (including the reason). The fallback SHOULD omit the spoiler text verbatim +since `body` might show up in text-only clients or in notifications. To prevent spoilers +showing up in such situations, clients are strongly encouraged to first upload the plaintext +to the media repository then reference the MXC URI in a markdown-style link, as shown above. + +Clients SHOULD render spoilers differently with some sort of disclosure. For example, the +client could blur the actual text and ask the user to click on it for it to be revealed. + #### Server behaviour Homeservers SHOULD reject `m.room.message` events which don't have a From 334fc56681fad132e9d320a4a59fc326d3ed04ff Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 5 Apr 2021 20:24:47 -0600 Subject: [PATCH 30/63] Changelog --- changelogs/client_server/newsfragments/3100.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/3100.feature diff --git a/changelogs/client_server/newsfragments/3100.feature b/changelogs/client_server/newsfragments/3100.feature new file mode 100644 index 00000000..259f1958 --- /dev/null +++ b/changelogs/client_server/newsfragments/3100.feature @@ -0,0 +1 @@ +Add `
` and `` to the suggested HTML subset as per [MSC2184](https://github.com/matrix-org/matrix-doc/pull/2184). \ No newline at end of file From 06d23f04aade446b2cf9d4c3b208eb35e235c593 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 5 Apr 2021 20:20:35 -0600 Subject: [PATCH 31/63] Changelog --- changelogs/client_server/newsfragments/3099.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/3099.clarification diff --git a/changelogs/client_server/newsfragments/3099.clarification b/changelogs/client_server/newsfragments/3099.clarification new file mode 100644 index 00000000..0e104a80 --- /dev/null +++ b/changelogs/client_server/newsfragments/3099.clarification @@ -0,0 +1 @@ +Clarify that event bodies are untrusted, as per [MSC2801](https://github.com/matrix-org/matrix-doc/pull/2801). \ No newline at end of file From 4fd262a237b4c74a81815849b04edca0ed423d41 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 5 Apr 2021 20:11:40 -0600 Subject: [PATCH 32/63] Changelog --- changelogs/client_server/newsfragments/3098.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/3098.feature diff --git a/changelogs/client_server/newsfragments/3098.feature b/changelogs/client_server/newsfragments/3098.feature new file mode 100644 index 00000000..0f3c3ab8 --- /dev/null +++ b/changelogs/client_server/newsfragments/3098.feature @@ -0,0 +1 @@ +Add support for spoilers ([MSC2010](https://github.com/matrix-org/matrix-doc/pull/2010) and [MSC2557](https://github.com/matrix-org/matrix-doc/pull/2557)), and `color` attribute ([MSC2422](https://github.com/matrix-org/matrix-doc/pull/2422)). \ No newline at end of file From 5d2cb50c5848564eae225cecad378991e8ed8fee Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 6 Apr 2021 09:59:10 -0600 Subject: [PATCH 33/63] Apply suggestions from code review Co-authored-by: Matthew Hodgson --- content/_index.md | 2 +- content/client-server-api/_index.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/content/_index.md b/content/_index.md index d28d5c4b..845fbc9f 100644 --- a/content/_index.md +++ b/content/_index.md @@ -233,7 +233,7 @@ reserved for events defined in the Matrix specification - for instance usually sent in the context of a "Room". {{% boxes/warning %}} -Event bodies are considered untrusted data. This means that anyone using +Event bodies are considered untrusted data. This means that any application using Matrix must validate that the event body is of the expected shape/schema before using the contents verbatim. diff --git a/content/client-server-api/_index.md b/content/client-server-api/_index.md index adace4f0..ed4d0399 100644 --- a/content/client-server-api/_index.md +++ b/content/client-server-api/_index.md @@ -1382,7 +1382,7 @@ available room versions. {{% /boxes/warning %}} {{% boxes/warning %}} -Event bodies are considered untrusted data. This means that anyone using +Event bodies are considered untrusted data. This means that any application using Matrix must validate that the event body is of the expected shape/schema before using the contents verbatim. From cee03d76255949420c9364abd29eefd6dac3c2a6 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Tue, 13 Apr 2021 15:20:51 -0400 Subject: [PATCH 34/63] Use the same domain for room ID and avatar URL. --- data/api/client-server/definitions/public_rooms_response.yaml | 2 +- data/api/server-server/public_rooms.yaml | 2 +- proposals/2403-knock.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/data/api/client-server/definitions/public_rooms_response.yaml b/data/api/client-server/definitions/public_rooms_response.yaml index ab701051..04680246 100644 --- a/data/api/client-server/definitions/public_rooms_response.yaml +++ b/data/api/client-server/definitions/public_rooms_response.yaml @@ -90,7 +90,7 @@ example: { "chunk": [ { "aliases": ["#murrays:cheese.bar"], - "avatar_url": "mxc://bleeker.street/CHEDDARandBRIE", + "avatar_url": "mxc://bleecker.street/CHEDDARandBRIE", "guest_can_join": false, "name": "CHEESE", "num_joined_members": 37, diff --git a/data/api/server-server/public_rooms.yaml b/data/api/server-server/public_rooms.yaml index 3c8d7ea6..e52f6d48 100644 --- a/data/api/server-server/public_rooms.yaml +++ b/data/api/server-server/public_rooms.yaml @@ -215,7 +215,7 @@ paths: "chunk": [ { "aliases": ["#murrays:cheese.bar"], - "avatar_url": "mxc://bleeker.street/CHEDDARandBRIE", + "avatar_url": "mxc://bleecker.street/CHEDDARandBRIE", "guest_can_join": false, "name": "CHEESE", "num_joined_members": 37, diff --git a/proposals/2403-knock.md b/proposals/2403-knock.md index 8bad1766..c0f39254 100644 --- a/proposals/2403-knock.md +++ b/proposals/2403-knock.md @@ -199,7 +199,7 @@ contain this information: "aliases": [ "#murrays:cheese.bar" ], - "avatar_url": "mxc://bleeker.street/CHEDDARandBRIE", + "avatar_url": "mxc://bleecker.street/CHEDDARandBRIE", "guest_can_join": false, "name": "CHEESE", "num_joined_members": 37, From 8f5c03927378a8e5e3e0349182dcf0f734377197 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 12 Apr 2021 21:55:46 -0600 Subject: [PATCH 35/63] Update readme for docs --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index bfcfd87d..a8bed3ce 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ The Matrix spec is compiled with [Hugo](https://gohugo.io/) (a static site gener * `/data`: this can contain TOML, YAML, or JSON files. Files kept here are directly available to template code as [data objects](https://gohugo.io/templates/data-templates/), so templates don't need to load them from a file and - parse them. This is also where our Swagger/OpenAPI definitions are. + parse them. This is also where our Swagger/OpenAPI definitions and schemas are. * `/layouts`: this contains [Hugo templates](https://gohugo.io/templates/). Some templates define the overall layout of a page: for example, whether it has header, footer, sidebar, and so on. @@ -49,7 +49,6 @@ Additionally, the following directories may be of interest: * `/attic`: Here contains historical sections of specification and legacy drafts for the specification. * `/changelogs`: Various bits of changelog for the specification areas. -* `/event-schemas`: [JSON Schema](http://json-schema.org/) definitions for the spec. * `/data-definitions`: Bits of structured data consumable by Matrix implementations. * `/meta`: Documentation relating to the spec's processes that are otherwise untracked (release instructions, etc). * `/scripts`: Various scripts for generating the spec and validating its contents. From 665c31e224abcd062ba12ae6a06f7d1060892158 Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Tue, 6 Apr 2021 17:20:15 +0100 Subject: [PATCH 36/63] Switch code formatting note about changelogs from RST to MD (#3103) --- CONTRIBUTING.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index e3db28fd..2e72e186 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -89,8 +89,8 @@ To create a changelog entry, create a file named in the format ``prNumber.type`` the ``newsfragments`` directory. The ``type`` can be one of the following: * ``new`` - Used when adding new endpoints. Please have the file contents be the - method and route being added, surrounded in RST code tags. For example: ``POST - /accounts/whoami`` + method and route being added, surrounded in markdown code tags. For example: \`POST + /accounts/whoami\`. * ``feature`` - Used when adding backwards-compatible changes to the API. From 456353c8b4eec374accf7afad63de7cf3e0ee21e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 13 Apr 2021 18:52:56 -0600 Subject: [PATCH 37/63] Add changelogs --- changelogs/client_server/newsfragments/3116.clarification | 1 + changelogs/server_server/newsfragments/3116.clarification | 1 + 2 files changed, 2 insertions(+) create mode 100644 changelogs/client_server/newsfragments/3116.clarification create mode 100644 changelogs/server_server/newsfragments/3116.clarification diff --git a/changelogs/client_server/newsfragments/3116.clarification b/changelogs/client_server/newsfragments/3116.clarification new file mode 100644 index 00000000..3ccb2333 --- /dev/null +++ b/changelogs/client_server/newsfragments/3116.clarification @@ -0,0 +1 @@ +Fix various typos throughout the specification. diff --git a/changelogs/server_server/newsfragments/3116.clarification b/changelogs/server_server/newsfragments/3116.clarification new file mode 100644 index 00000000..3ccb2333 --- /dev/null +++ b/changelogs/server_server/newsfragments/3116.clarification @@ -0,0 +1 @@ +Fix various typos throughout the specification. From cfc55b243d8610763777083162d00be69995fedf Mon Sep 17 00:00:00 2001 From: Devin Ragotzy Date: Fri, 16 Apr 2021 08:07:17 -0400 Subject: [PATCH 38/63] Fix user ID examples in direct_to_device schema --- .../definitions/event-schemas/m.direct_to_device.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/api/server-server/definitions/event-schemas/m.direct_to_device.yaml b/data/api/server-server/definitions/event-schemas/m.direct_to_device.yaml index 916922cf..f628ebe0 100644 --- a/data/api/server-server/definitions/event-schemas/m.direct_to_device.yaml +++ b/data/api/server-server/definitions/event-schemas/m.direct_to_device.yaml @@ -35,7 +35,7 @@ allOf: sender: type: string description: User ID of the sender. - example: "john@example.com" + example: "@john:example.com" type: type: string description: Event type for the message. @@ -59,7 +59,7 @@ allOf: title: Device Message Contents properties: {} example: { - "alice@example.org": { + "@alice:example.org": { "IWHQUZUIAH": { "algorithm": "m.megolm.v1.aes-sha2", "room_id": "!Cuyf34gef24t:localhost", From 5e211480bff992d7d845a0f916aeac8739bbd130 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 16 Apr 2021 09:56:02 -0600 Subject: [PATCH 39/63] add changelog --- changelogs/server_server/newsfragments/3128.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/server_server/newsfragments/3128.clarification diff --git a/changelogs/server_server/newsfragments/3128.clarification b/changelogs/server_server/newsfragments/3128.clarification new file mode 100644 index 00000000..3ccb2333 --- /dev/null +++ b/changelogs/server_server/newsfragments/3128.clarification @@ -0,0 +1 @@ +Fix various typos throughout the specification. From a855ed338b6dd671be2dc369684a9d976d78dc6f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 16 Apr 2021 03:25:30 -0600 Subject: [PATCH 40/63] Fix event size restriction (#3127) Fixes https://github.com/matrix-org/matrix-doc/issues/3126 --- changelogs/client_server/newsfragments/3127.clarification | 1 + content/client-server-api/_index.md | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 changelogs/client_server/newsfragments/3127.clarification diff --git a/changelogs/client_server/newsfragments/3127.clarification b/changelogs/client_server/newsfragments/3127.clarification new file mode 100644 index 00000000..d858e2b7 --- /dev/null +++ b/changelogs/client_server/newsfragments/3127.clarification @@ -0,0 +1 @@ +Fix the maximum event size restriction (65535 bytes -> 65536). diff --git a/content/client-server-api/_index.md b/content/client-server-api/_index.md index ed4d0399..a5964fe7 100644 --- a/content/client-server-api/_index.md +++ b/content/client-server-api/_index.md @@ -1447,7 +1447,7 @@ following fields. ### Size limits -The complete event MUST NOT be larger than 65535 bytes, when formatted +The complete event MUST NOT be larger than 65536 bytes, when formatted as a [PDU for the Server-Server protocol](/server-server-api/#pdus), including any signatures, and encoded as [Canonical @@ -1463,7 +1463,7 @@ There are additional restrictions on sizes per key: Some event types have additional size restrictions which are specified in the description of the event. Additional keys have no limit other -than that implied by the total 65 KB limit on events. +than that implied by the total 64 KiB limit on events. ### Room Events From b5bdfffa53f408f8cda3f256ce14948c6c86eb31 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 20 Apr 2021 18:54:00 -0400 Subject: [PATCH 41/63] spec verification in DMs and m.key.verification.ready/done --- .../modules/end_to_end_encryption.md | 186 ++++++++++++------ .../examples/m.key.verification.done.yaml | 6 + .../examples/m.key.verification.ready.yaml | 10 + .../schema/m.key.verification.accept.yaml | 12 +- .../schema/m.key.verification.cancel.yaml | 9 +- .../schema/m.key.verification.done.yaml | 23 +++ .../schema/m.key.verification.key.yaml | 12 +- .../m.key.verification.m.relates_to.yaml | 21 ++ .../schema/m.key.verification.mac.yaml | 12 +- .../schema/m.key.verification.ready.yaml | 40 ++++ .../schema/m.key.verification.request.yaml | 17 +- .../m.key.verification.start$m.sas.v1.yaml | 15 +- .../schema/m.key.verification.start.yaml | 13 +- 13 files changed, 283 insertions(+), 93 deletions(-) create mode 100644 data/event-schemas/examples/m.key.verification.done.yaml create mode 100644 data/event-schemas/examples/m.key.verification.ready.yaml create mode 100644 data/event-schemas/schema/m.key.verification.done.yaml create mode 100644 data/event-schemas/schema/m.key.verification.m.relates_to.yaml create mode 100644 data/event-schemas/schema/m.key.verification.ready.yaml diff --git a/content/client-server-api/modules/end_to_end_encryption.md b/content/client-server-api/modules/end_to_end_encryption.md index b5a444a4..35cd5e9e 100644 --- a/content/client-server-api/modules/end_to_end_encryption.md +++ b/content/client-server-api/modules/end_to_end_encryption.md @@ -357,7 +357,7 @@ out-of-band channel: there is no way to do it within Matrix without trusting the administrators of the homeservers. In Matrix, verification works by Alice meeting Bob in person, or -contacting him via some other trusted medium, and use [SAS +contacting him via some other trusted medium, and using [SAS Verification](#SAS Verification) to interactively verify Bob's devices. Alice and Bob may also read aloud their unpadded base64 encoded Ed25519 public key, as returned by `/keys/query`. @@ -390,60 +390,68 @@ decrypted by such a device. For the Olm protocol, this is documented at Verifying keys manually by reading out the Ed25519 key is not very user-friendly, and can lead to errors. In order to help mitigate errors, and to make the process easier for users, some verification methods are -supported by the specification. The methods all use a common framework +supported by the specification and use messages exchanged by the user's devices +to assist in the verification. The methods all use a common framework for negotiating the key verification. -To use this framework, Alice's client would send -`m.key.verification.request` events to Bob's devices. All of the -`to_device` messages sent to Bob MUST have the same `transaction_id` to -indicate they are part of the same request. This allows Bob to reject -the request on one device, and have it apply to all of his devices. -Similarly, it allows Bob to process the verification on one device -without having to involve all of his devices. - -When Bob's device receives an `m.key.verification.request`, it should -prompt Bob to verify keys with Alice using one of the supported methods -in the request. If Bob's device does not understand any of the methods, -it should not cancel the request as one of his other devices may support -the request. Instead, Bob's device should tell Bob that an unsupported -method was used for starting key verification. The prompt for Bob to -accept/reject Alice's request (or the unsupported method prompt) should -be automatically dismissed 10 minutes after the `timestamp` field or 2 -minutes after Bob's client receives the message, whichever comes first, -if Bob does not interact with the prompt. The prompt should additionally -be hidden if an appropriate `m.key.verification.cancel` message is -received. - -If Bob rejects the request, Bob's client must send an -`m.key.verification.cancel` message to Alice's device. Upon receipt, -Alice's device should tell her that Bob does not want to verify her -device and send `m.key.verification.cancel` messages to all of Bob's -devices to notify them that the request was rejected. - -If Bob accepts the request, Bob's device starts the key verification -process by sending an `m.key.verification.start` message to Alice's -device. Upon receipt of this message, Alice's device should send an -`m.key.verification.cancel` message to all of Bob's other devices to -indicate the process has been started. The start message must use the -same `transaction_id` from the original key verification request if it -is in response to the request. The start message can be sent -independently of any request. - -Individual verification methods may add additional steps, events, and -properties to the verification messages. Event types for methods defined -in this specification must be under the `m.key.verification` namespace -and any other event types must be namespaced according to the Java -package naming convention. - -Any of Alice's or Bob's devices can cancel the key verification request -or process at any time with an `m.key.verification.cancel` message to -all applicable devices. - -This framework yields the following handshake, assuming both Alice and -Bob each have 2 devices, Bob's first device accepts the key verification -request, and Alice's second device initiates the request. Note how -Alice's first device is not involved in the request or verification -process. +Verification messages can be sent either in a room shared by the two parties, +which should be a [direct messaging](#direct-messaging) room between the two +parties, or by using [to-device](#send-to-device-messaging) messages sent +directly between the two devices involved. In both cases, the messages +exchanged are similar, with minor differences as detailed below. Verifying +between two different users should be performed using in-room messages, whereas +verifying two devices belonging to the same user should be performed using +to-device messages. + +A key verification session is identified by an ID that is established by the +first message sent in that session. For verifications using in-room messages, +the ID is the event ID of the initial message, and for verifications using +to-device messages, the first message contains a `transaction_id` field that is +shared by the other messages of that session. + +In general, verification operates as follows: + +- Alice requests a key verification with Bob by sending an + `m.key.verification.request` event. This event indicates the verification + methods that Alice's client supports. (Note that "Alice" and "Bob" may in + fact be the same user, in the case where a user is verifying their own + devices.) +- Bob's client prompts Bob to accepts the key verification. When Bob accepts + the verification, Bob's client sends an `m.key.verification.ready` event. + This event indicates the verification methods, corresponding to the + verification methods supported by Alice's client, that Bob's client supports. +- Alice's or Bob's devices allow their users to select one of the verification + methods supported by both devices to use for verification. When Alice or Bob + selects a verification method, their device begins the verification by + sending an `m.key.verification.start` event, indicating the selected + verification method. +- Alice and Bob complete the verification as defined by the selected + verification method. This could involve their clients exchanging messages, + Alice and Bob exchanging information out-of-band, and/or Alice and Bob + interacting with their devices. +- Alice's and Bob's clients send `m.key.verification.done` events to indicate + that the verification was successful. + +Verifications can be cancelled by either device at any time by sending an +`m.key.verification.cancel` event with a `code` field that indicates the reason +it was cancelled. + +When using to-device messages, Alice may not know which of Bob's devices to +verify, or may not want to choose a specific device. In this case, Alice will +send `m.key.verification.request` events to all of Bob's devices. All of these +events will use the same transaction ID. When Bob accepts or declines the +verification on one of his devices (sending either an +`m.key.verification.ready` or `m.key.verification.cancel` event), Alice will +send an `m.key.verification.cancel` event to Bob's other devices with a `code` +of `m.accepted` in the case where Bob accepted the verification, or `m.user` in +the case where Bob rejected the verification. This yields the following +handshake when using to-device messages, assuming both Alice and Bob each have +2 devices, Bob's first device accepts the key verification request, and Alice's +second device initiates the request. Note how Alice's first device is not +involved in the request or verification process. Also note that, although in +this example, Bob's device sends the `m.key.verification.start`, Alice's device +could also send that message. As well, the order of the +`m.key.verification.done` messages could be reversed. ``` +---------------+ +---------------+ +-------------+ +-------------+ @@ -456,20 +464,84 @@ process. | | m.key.verification.request | | | |-------------------------------------------------->| | | | | - | | m.key.verification.start | | + | | m.key.verification.ready | | | |<----------------------------------| | | | | | | | m.key.verification.cancel | | | |-------------------------------------------------->| | | | | + | | m.key.verification.start | | + | |<----------------------------------| | + | | | | + . + . (verification messages) + . + | | | | + | | m.key.verification.done | | + | |<----------------------------------| | + | | | | + | | m.key.verification.done | | + | |---------------------------------->| | + | | | | ``` -After the handshake, the verification process begins. +When using in-room messages and the room has encryption enabled, clients should +ensure that encryption does not hinder the verification. For example, if the +verification messages are encrypted, clients must ensure that all the +recipient's unverified devices receive the keys necessary to decrypt the +messages, even if they would normally not be given the keys to decrypt messages +in the room. Alternatively, verification messages may be sent unencrypted. + +Upon receipt of Alice's `m.key.verification.request` message, if Bob's device +does not understand any of the methods, it should not cancel the request as one +of his other devices may support the request. Instead, Bob's device should tell +Bob that no supported method was found, and allow him to manually reject the +request. + +The prompt for Bob to accept/reject Alice's request (or the unsupported method +prompt) should be automatically dismissed 10 minutes after the `timestamp` (in +the case of to-device messages) or `origin_ts` (in the case of in-room +messages) field or 2 minutes after Bob's client receives the message, whichever +comes first, if Bob does not interact with the prompt. The prompt should +additionally be hidden if an appropriate `m.key.verification.cancel` message is +received. + +If Bob rejects the request, Bob's client must send an +`m.key.verification.cancel` event with `code` set to `m.user`. Upon receipt, +Alice's device should tell her that Bob does not want to verify her device and, +if the request was sent as a to-device message, send +`m.key.verification.cancel` messages to all of Bob's devices to notify them +that the request was rejected. + +If Alice's and Bob's clients both send an `m.key.verification.start` message, +and both specify the same verification method, then the +`m.key.verification.start` message sent by the user whose ID is the +lexicographically largest user ID should be ignored, and the situation should +be treated the same as if only the user with the lexicographically smallest +user ID had sent the `m.key.verification.start` message. In the case where the +user IDs are the same (that is, when a user is verifying their own device), +then the device IDs should be compared instead. If the two +`m.key.verification.start` messages do not specify the same verification +method, then the verification should be cancelled with a `code` of +`m.unexpected_message`. + +An `m.key.verification.start` message can also be sent independently of any +request, specifying the verification method to use. + +Individual verification methods may add additional steps, events, and +properties to the verification messages. Event types for methods defined +in this specification must be under the `m.key.verification` namespace +and any other event types must be namespaced according to the Java +package naming convention. {{% event event="m.key.verification.request" %}} +{{% event event="m.key.verification.ready" %}} + {{% event event="m.key.verification.start" %}} +{{% event event="m.key.verification.done" %}} + {{% event event="m.key.verification.cancel" %}} ##### Short Authentication String (SAS) verification @@ -493,6 +565,10 @@ example, if we verify 40 bits, then an attacker has a 1 in success. A failed attack would result in a mismatched Short Authentication String, alerting users to the attack. +To advertise support for this method, clients use the name `m.sas.v1` in the +`methods` fields of the `m.key.verification.request` and +`m.key.verification.ready` events. + The verification process takes place over [to-device](#send-to-device-messaging) messages in two phases: diff --git a/data/event-schemas/examples/m.key.verification.done.yaml b/data/event-schemas/examples/m.key.verification.done.yaml new file mode 100644 index 00000000..0e883cf1 --- /dev/null +++ b/data/event-schemas/examples/m.key.verification.done.yaml @@ -0,0 +1,6 @@ +{ + "type": "m.key.verification.done", + "content": { + "transaction_id": "S0meUniqueAndOpaqueString" + } +} diff --git a/data/event-schemas/examples/m.key.verification.ready.yaml b/data/event-schemas/examples/m.key.verification.ready.yaml new file mode 100644 index 00000000..0397a566 --- /dev/null +++ b/data/event-schemas/examples/m.key.verification.ready.yaml @@ -0,0 +1,10 @@ +{ + "type": "m.key.verification.ready", + "content": { + "from_device": "BobDevice1", + "transaction_id": "S0meUniqueAndOpaqueString", + "methods": [ + "m.sas.v1" + ] + } +} diff --git a/data/event-schemas/schema/m.key.verification.accept.yaml b/data/event-schemas/schema/m.key.verification.accept.yaml index 92ff6dfc..ae63995b 100644 --- a/data/event-schemas/schema/m.key.verification.accept.yaml +++ b/data/event-schemas/schema/m.key.verification.accept.yaml @@ -3,16 +3,16 @@ allOf: - $ref: core-event-schema/event.yaml description: |- - Accepts a previously sent `m.key.verification.start` message. Typically sent as a - [to-device](/client-server-api/#send-to-device-messaging) event. + Accepts a previously sent `m.key.verification.start` message. properties: content: properties: transaction_id: type: string description: |- - An opaque identifier for the verification process. Must be the same as - the one used for the `m.key.verification.start` message. + Required when sent as a to-device message. An opaque identifier for + the verification process. Must be the same as the one used for the + `m.key.verification.start` message. key_agreement_protocol: type: string description: |- @@ -43,8 +43,10 @@ properties: The hash (encoded as unpadded base64) of the concatenation of the device's ephemeral public key (encoded as unpadded base64) and the canonical JSON representation of the `m.key.verification.start` message. + m.relates_to: + allOf: + - $ref: m.key.verification.m.relates_to.yaml required: - - transaction_id - method - key_agreement_protocol - hash diff --git a/data/event-schemas/schema/m.key.verification.cancel.yaml b/data/event-schemas/schema/m.key.verification.cancel.yaml index 1c6cd841..6474b763 100644 --- a/data/event-schemas/schema/m.key.verification.cancel.yaml +++ b/data/event-schemas/schema/m.key.verification.cancel.yaml @@ -3,14 +3,15 @@ allOf: - $ref: core-event-schema/event.yaml description: |- - Cancels a key verification process/request. Typically sent as a [to-device](/client-server-api/#send-to-device-messaging) event. + Cancels a key verification process/request. properties: content: properties: transaction_id: type: string description: |- - The opaque identifier for the verification process/request. + Required when sent as a to-device message. The opaque identifier for + the verification process/request. reason: type: string description: |- @@ -56,8 +57,10 @@ properties: gets an unexpected response with `m.unexpected_message`, the client should not respond again with `m.unexpected_message` to avoid the other device potentially sending another error response. + m.relates_to: + allOf: + - $ref: m.key.verification.m.relates_to.yaml required: - - transaction_id - code - reason type: object diff --git a/data/event-schemas/schema/m.key.verification.done.yaml b/data/event-schemas/schema/m.key.verification.done.yaml new file mode 100644 index 00000000..bfdc540b --- /dev/null +++ b/data/event-schemas/schema/m.key.verification.done.yaml @@ -0,0 +1,23 @@ +--- +allOf: + - $ref: core-event-schema/event.yaml + +description: |- + Indicates that a verification process/request has completed successfully. +properties: + content: + properties: + transaction_id: + type: string + description: |- + Required when sent as a to-device message. The opaque identifier for + the verification process/request. + m.relates_to: + allOf: + - $ref: m.key.verification.m.relates_to.yaml + type: object + type: + enum: + - m.key.verification.done + type: string +type: object diff --git a/data/event-schemas/schema/m.key.verification.key.yaml b/data/event-schemas/schema/m.key.verification.key.yaml index 34993bd4..62704ea7 100644 --- a/data/event-schemas/schema/m.key.verification.key.yaml +++ b/data/event-schemas/schema/m.key.verification.key.yaml @@ -3,22 +3,24 @@ allOf: - $ref: core-event-schema/event.yaml description: |- - Sends the ephemeral public key for a device to the partner device. Typically sent as a - [to-device](/client-server-api/#send-to-device-messaging) event. + Sends the ephemeral public key for a device to the partner device. properties: content: properties: transaction_id: type: string description: |- - An opaque identifier for the verification process. Must be the same as - the one used for the `m.key.verification.start` message. + Required when sent as a to-device message. An opaque identifier for + the verification process. Must be the same as the one used for the + `m.key.verification.start` message. key: type: string description: |- The device's ephemeral public key, encoded as unpadded base64. + m.relates_to: + allOf: + - $ref: m.key.verification.m.relates_to.yaml required: - - transaction_id - key type: object type: diff --git a/data/event-schemas/schema/m.key.verification.m.relates_to.yaml b/data/event-schemas/schema/m.key.verification.m.relates_to.yaml new file mode 100644 index 00000000..e29f8bbe --- /dev/null +++ b/data/event-schemas/schema/m.key.verification.m.relates_to.yaml @@ -0,0 +1,21 @@ +--- +description: |- + Required when sent as an in-room message. Indicates the + `m.key.verification.request` that this message is related to. Note that for + encrypted messages, this property should be in the unencrypted portion of the + event. +properties: + rel_type: + type: string + enum: + - m.reference + description: |- + The relationship type. + event_id: + type: string + description: |- + The event ID of the `m.key.verification.request` that this message is + related to. + type: object +type: object +title: VerificationRelatesTo diff --git a/data/event-schemas/schema/m.key.verification.mac.yaml b/data/event-schemas/schema/m.key.verification.mac.yaml index eec5d65b..9f7f5f4f 100644 --- a/data/event-schemas/schema/m.key.verification.mac.yaml +++ b/data/event-schemas/schema/m.key.verification.mac.yaml @@ -3,16 +3,16 @@ allOf: - $ref: core-event-schema/event.yaml description: |- - Sends the MAC of a device's key to the partner device. Typically sent as a - [to-device](/client-server-api/#send-to-device-messaging) event. + Sends the MAC of a device's key to the partner device. properties: content: properties: transaction_id: type: string description: |- - An opaque identifier for the verification process. Must be the same as - the one used for the `m.key.verification.start` message. + Required when sent as a to-device message. An opaque identifier for + the verification process. Must be the same as the one used for the + `m.key.verification.start` message. mac: type: object description: |- @@ -26,8 +26,10 @@ properties: description: |- The MAC of the comma-separated, sorted, list of key IDs given in the `mac` property, encoded as unpadded base64. + m.relates_to: + allOf: + - $ref: m.key.verification.m.relates_to.yaml required: - - transaction_id - mac - keys type: object diff --git a/data/event-schemas/schema/m.key.verification.ready.yaml b/data/event-schemas/schema/m.key.verification.ready.yaml new file mode 100644 index 00000000..bf9d975b --- /dev/null +++ b/data/event-schemas/schema/m.key.verification.ready.yaml @@ -0,0 +1,40 @@ +--- +allOf: + - $ref: core-event-schema/event.yaml + +description: |- + Accepts a key verification request. Sent in response to an + `m.key.verification.request` event. +properties: + content: + properties: + from_device: + type: string + description: |- + The device ID which is accepting the request. + transaction_id: + type: string + description: |- + Required when sent as a to-device message. The transaction ID of the + verification request, as given in the `m.key.verification.request` + message. + methods: + type: array + description: |- + The verification methods supported by the sender, corresponding to + the verification methods indicated in the + `m.key.verification.request` message. + items: + type: string + m.relates_to: + allOf: + - $ref: m.key.verification.m.relates_to.yaml + required: + - from_device + - methods + type: object + type: + enum: + - m.key.verification.ready + type: string +type: object diff --git a/data/event-schemas/schema/m.key.verification.request.yaml b/data/event-schemas/schema/m.key.verification.request.yaml index 05e88b0f..7732cf38 100644 --- a/data/event-schemas/schema/m.key.verification.request.yaml +++ b/data/event-schemas/schema/m.key.verification.request.yaml @@ -3,8 +3,7 @@ allOf: - $ref: core-event-schema/event.yaml description: |- - Requests a key verification with another user's devices. Typically sent as a - [to-device](/client-server-api/#send-to-device-messaging) event. + Requests a key verification with another user's devices. properties: content: properties: @@ -15,8 +14,9 @@ properties: transaction_id: type: string description: |- - An opaque identifier for the verification request. Must be unique - with respect to the devices involved. + Required when sent as a to-device message. An opaque identifier for + the verification request. Must be unique with respect to the devices + involved. methods: type: array description: |- @@ -27,14 +27,13 @@ properties: type: integer format: int64 description: |- - The POSIX timestamp in milliseconds for when the request was made. If - the request is in the future by more than 5 minutes or more than 10 - minutes in the past, the message should be ignored by the receiver. + Required when sent as a to-device message. The POSIX timestamp in + milliseconds for when the request was made. If the request is in the + future by more than 5 minutes or more than 10 minutes in the past, + the message should be ignored by the receiver. required: - from_device - - transaction_id - methods - - timestamp type: object type: enum: diff --git a/data/event-schemas/schema/m.key.verification.start$m.sas.v1.yaml b/data/event-schemas/schema/m.key.verification.start$m.sas.v1.yaml index aa833549..515a72a1 100644 --- a/data/event-schemas/schema/m.key.verification.start$m.sas.v1.yaml +++ b/data/event-schemas/schema/m.key.verification.start$m.sas.v1.yaml @@ -3,7 +3,7 @@ allOf: - $ref: core-event-schema/event.yaml description: |- - Begins a SAS key verification process using the `m.sas.v1` method. Typically sent as a [to-device](/client-server-api/#send-to-device-messaging) event. + Begins a SAS key verification process using the `m.sas.v1` method. properties: content: properties: @@ -14,10 +14,11 @@ properties: transaction_id: type: string description: |- - An opaque identifier for the verification process. Must be unique - with respect to the devices involved. Must be the same as the - `transaction_id` given in the `m.key.verification.request` - if this process is originating from a request. + Required when sent as a to-device message. An opaque identifier for + the verification process. Must be unique with respect to the devices + involved. Must be the same as the `transaction_id` given in the + `m.key.verification.request` if this process is originating from a + request. method: type: string enum: ["m.sas.v1"] @@ -53,9 +54,11 @@ properties: items: type: string enum: ["decimal", "emoji"] + m.relates_to: + allOf: + - $ref: m.key.verification.m.relates_to.yaml required: - from_device - - transaction_id - method - key_agreement_protocols - hashes diff --git a/data/event-schemas/schema/m.key.verification.start.yaml b/data/event-schemas/schema/m.key.verification.start.yaml index 0cc60cb2..a36a72f8 100644 --- a/data/event-schemas/schema/m.key.verification.start.yaml +++ b/data/event-schemas/schema/m.key.verification.start.yaml @@ -16,10 +16,11 @@ properties: transaction_id: type: string description: |- - An opaque identifier for the verification process. Must be unique - with respect to the devices involved. Must be the same as the - `transaction_id` given in the `m.key.verification.request` - if this process is originating from a request. + Required when sent as a to-device message. An opaque identifier for + the verification process. Must be unique with respect to the devices + involved. Must be the same as the `transaction_id` given in the + `m.key.verification.request` if this process is originating from a + request. method: type: string description: |- @@ -30,9 +31,11 @@ properties: Optional method to use to verify the other user's key with. Applicable when the `method` chosen only verifies one user's key. This field will never be present if the `method` verifies keys both ways. + m.relates_to: + allOf: + - $ref: m.key.verification.m.relates_to.yaml required: - from_device - - transaction_id - method type: object type: From 8a7a023d3c01602423e12f9c9ea248d9f26d07b0 Mon Sep 17 00:00:00 2001 From: Thibault Martin Date: Thu, 8 Apr 2021 06:33:25 +0000 Subject: [PATCH 42/63] Translated using Weblate (French) Currently translated at 100.0% (64 of 64 strings) Translation: matrix-doc/SAS Emoji v1 Translate-URL: https://translate.element.io/projects/matrix-doc/sas-emoji-v1/fr/ --- data-definitions/sas-emoji-v1-i18n/fr.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data-definitions/sas-emoji-v1-i18n/fr.json b/data-definitions/sas-emoji-v1-i18n/fr.json index 7996c108..6d754091 100644 --- a/data-definitions/sas-emoji-v1-i18n/fr.json +++ b/data-definitions/sas-emoji-v1-i18n/fr.json @@ -18,7 +18,7 @@ "Pizza": "Pizza", "Cake": "Gâteau", "Heart": "Cœur", - "Hat": "Châpeau", + "Hat": "Chapeau", "Glasses": "Lunettes", "Hourglass": "Sablier", "Book": "Livre", @@ -41,7 +41,7 @@ "Robot": "Robot", "Spanner": "Clé à molette", "Santa": "Père Noël", - "Thumbs Up": "Pouce en l'air", + "Thumbs Up": "Pouce en l’air", "Umbrella": "Parapluie", "Clock": "Réveil", "Gift": "Cadeau", From de1a468630b1aa5300926af08096f7480e0beb2a Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 20 Apr 2021 19:24:36 -0400 Subject: [PATCH 43/63] add changelog --- changelogs/client_server/newsfragments/3139.breaking | 1 + changelogs/client_server/newsfragments/3139.feature | 1 + 2 files changed, 2 insertions(+) create mode 100644 changelogs/client_server/newsfragments/3139.breaking create mode 100644 changelogs/client_server/newsfragments/3139.feature diff --git a/changelogs/client_server/newsfragments/3139.breaking b/changelogs/client_server/newsfragments/3139.breaking new file mode 100644 index 00000000..755afc35 --- /dev/null +++ b/changelogs/client_server/newsfragments/3139.breaking @@ -0,0 +1 @@ +Add `m.key.verification.ready` and `m.key.verification.done` to key verification framework as per [MSC2366](https://github.com/matrix-org/matrix-doc/pull/2366). diff --git a/changelogs/client_server/newsfragments/3139.feature b/changelogs/client_server/newsfragments/3139.feature new file mode 100644 index 00000000..37331065 --- /dev/null +++ b/changelogs/client_server/newsfragments/3139.feature @@ -0,0 +1 @@ +Add key verification using in-room messages as per [MSC2241](https://github.com/matrix-org/matrix-doc/pull/2241). From 4183893ec2597ee93c2adbae350c0293bae5d406 Mon Sep 17 00:00:00 2001 From: Hakim Oubouali Date: Tue, 27 Apr 2021 09:40:23 +0000 Subject: [PATCH 44/63] Added translation using Weblate (Central Atlas Tamazight) --- data-definitions/sas-emoji-v1-i18n/tzm.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 data-definitions/sas-emoji-v1-i18n/tzm.json diff --git a/data-definitions/sas-emoji-v1-i18n/tzm.json b/data-definitions/sas-emoji-v1-i18n/tzm.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/data-definitions/sas-emoji-v1-i18n/tzm.json @@ -0,0 +1 @@ +{} From 1638d2f32eb2c9fea7550bd92f5c91ae0b48129b Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 22 Apr 2021 14:12:56 -0400 Subject: [PATCH 45/63] Apply suggestions from code review Co-authored-by: Travis Ralston --- .../client-server-api/modules/end_to_end_encryption.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/content/client-server-api/modules/end_to_end_encryption.md b/content/client-server-api/modules/end_to_end_encryption.md index 35cd5e9e..16cd3178 100644 --- a/content/client-server-api/modules/end_to_end_encryption.md +++ b/content/client-server-api/modules/end_to_end_encryption.md @@ -416,7 +416,7 @@ In general, verification operates as follows: methods that Alice's client supports. (Note that "Alice" and "Bob" may in fact be the same user, in the case where a user is verifying their own devices.) -- Bob's client prompts Bob to accepts the key verification. When Bob accepts +- Bob's client prompts Bob to accept the key verification. When Bob accepts the verification, Bob's client sends an `m.key.verification.ready` event. This event indicates the verification methods, corresponding to the verification methods supported by Alice's client, that Bob's client supports. @@ -424,7 +424,9 @@ In general, verification operates as follows: methods supported by both devices to use for verification. When Alice or Bob selects a verification method, their device begins the verification by sending an `m.key.verification.start` event, indicating the selected - verification method. + verification method. Note that if there is only one verification method in + common between the devices then the receiver's device (Bob) can auto-select + it. - Alice and Bob complete the verification as defined by the selected verification method. This could involve their clients exchanging messages, Alice and Bob exchanging information out-of-band, and/or Alice and Bob @@ -490,7 +492,8 @@ ensure that encryption does not hinder the verification. For example, if the verification messages are encrypted, clients must ensure that all the recipient's unverified devices receive the keys necessary to decrypt the messages, even if they would normally not be given the keys to decrypt messages -in the room. Alternatively, verification messages may be sent unencrypted. +in the room. Alternatively, verification messages may be sent unencrypted, +though this is not encouraged. Upon receipt of Alice's `m.key.verification.request` message, if Bob's device does not understand any of the methods, it should not cancel the request as one From 0b823e0b036a888c2078959615e8a7cbdaf324b3 Mon Sep 17 00:00:00 2001 From: Hakim Oubouali Date: Tue, 27 Apr 2021 09:46:19 +0000 Subject: [PATCH 46/63] Translated using Weblate (Central Atlas Tamazight) Currently translated at 40.6% (26 of 64 strings) Translation: matrix-doc/SAS Emoji v1 Translate-URL: https://translate.element.io/projects/matrix-doc/sas-emoji-v1/tzm/ --- data-definitions/sas-emoji-v1-i18n/tzm.json | 29 ++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/data-definitions/sas-emoji-v1-i18n/tzm.json b/data-definitions/sas-emoji-v1-i18n/tzm.json index 0967ef42..1045169c 100644 --- a/data-definitions/sas-emoji-v1-i18n/tzm.json +++ b/data-definitions/sas-emoji-v1-i18n/tzm.json @@ -1 +1,28 @@ -{} +{ + "Folder": "Asdaw", + "Guitar": "Agiṭaṛ", + "Ball": "Tcama", + "Flag": "Acenyal", + "Telephone": "Atilifun", + "Key": "Tasarut", + "Book": "Adlis", + "Hat": "Taraza", + "Robot": "Aṛubu", + "Heart": "Ul", + "Apple": "Tadeffuyt", + "Banana": "Tabanant", + "Fire": "Timessi", + "Moon": "Ayyur", + "Mushroom": "Agursel", + "Tree": "Aseklu", + "Fish": "Aselm", + "Turtle": "Ifker", + "Rooster": "Ayaẓiḍ", + "Rabbit": "Agnin", + "Elephant": "Ilu", + "Pig": "Ilef", + "Horse": "Ayyis", + "Lion": "Izem", + "Cat": "Amuc", + "Dog": "Aydi" +} From fd5da297d8838844f40a0d8e225b20164c6555ad Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 27 Apr 2021 20:59:21 -0400 Subject: [PATCH 47/63] Make SAS outline fit with key verification in DM flow. --- .../modules/end_to_end_encryption.md | 47 +++++++++---------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/content/client-server-api/modules/end_to_end_encryption.md b/content/client-server-api/modules/end_to_end_encryption.md index 16cd3178..332fb55a 100644 --- a/content/client-server-api/modules/end_to_end_encryption.md +++ b/content/client-server-api/modules/end_to_end_encryption.md @@ -247,8 +247,7 @@ file type. The key is sent using the [JSON Web Key](https://tools.ietf.org/html/rfc7517#appendix-A.3) format, with a [W3C extension](https://w3c.github.io/webcrypto/#iana-section-jwk). -Extensions to `m.room.message` msgtypes -<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +###### Extensions to `m.room.message` msgtypes This module adds `file` and `thumbnail_file` properties, of type `EncryptedFile`, to `m.room.message` msgtypes that reference files, such @@ -572,8 +571,7 @@ To advertise support for this method, clients use the name `m.sas.v1` in the `methods` fields of the `m.key.verification.request` and `m.key.verification.ready` events. -The verification process takes place over [to-device](#send-to-device-messaging) messages in two -phases: +The verification process takes place in two phases: 1. Key agreement phase (based on [ZRTP key agreement](https://tools.ietf.org/html/rfc6189#section-4.4.1)). @@ -584,63 +582,62 @@ The process between Alice and Bob verifying each other would be: 1. Alice and Bob establish a secure out-of-band connection, such as meeting in-person or a video call. "Secure" here means that either party cannot be impersonated, not explicit secrecy. -2. Alice and Bob communicate which devices they'd like to verify with - each other. -3. Alice selects Bob's device from the device list and begins - verification. -4. Alice's client ensures it has a copy of Bob's device key. -5. Alice's device sends Bob's device an `m.key.verification.start` - message. -6. Bob's device receives the message and selects a key agreement +2. Alice and Bob begin a key verification using the key verification + framework as described above. +3. Alice's device sends Bob's device an `m.key.verification.start` + message. Alice's client ensures it has a copy of Bob's device key. +4. Bob's device receives the message and selects a key agreement protocol, hash algorithm, message authentication code, and SAS method supported by Alice's device. -7. Bob's device ensures it has a copy of Alice's device key. -8. Bob's device creates an ephemeral Curve25519 key pair +5. Bob's device ensures it has a copy of Alice's device key. +6. Bob's device creates an ephemeral Curve25519 key pair (*KBprivate*, *KBpublic*), and calculates the hash (using the chosen algorithm) of the public key *KBpublic*. -9. Bob's device replies to Alice's device with an +7. Bob's device replies to Alice's device with an `m.key.verification.accept` message. -10. Alice's device receives Bob's message and stores the commitment hash +8. Alice's device receives Bob's message and stores the commitment hash for later use. -11. Alice's device creates an ephemeral Curve25519 key pair +9. Alice's device creates an ephemeral Curve25519 key pair (*KAprivate*, *KApublic*) and replies to Bob's device with an `m.key.verification.key`, sending only the public key *KApublic*. -12. Bob's device receives Alice's message and replies with its own +10. Bob's device receives Alice's message and replies with its own `m.key.verification.key` message containing its public key *KBpublic*. -13. Alice's device receives Bob's message and verifies the commitment +11. Alice's device receives Bob's message and verifies the commitment hash from earlier matches the hash of the key Bob's device just sent and the content of Alice's `m.key.verification.start` message. -14. Both Alice and Bob's devices perform an Elliptic-curve +12. Both Alice and Bob's devices perform an Elliptic-curve Diffie-Hellman (*ECDH(KAprivate*, *KBpublic*)), using the result as the shared secret. -15. Both Alice and Bob's devices display a SAS to their users, which is +13. Both Alice and Bob's devices display a SAS to their users, which is derived from the shared key using one of the methods in this section. If multiple SAS methods are available, clients should allow the users to select a method. -16. Alice and Bob compare the strings shown by their devices, and tell +14. Alice and Bob compare the strings shown by their devices, and tell their devices if they match or not. -17. Assuming they match, Alice and Bob's devices calculate the HMAC of +15. Assuming they match, Alice and Bob's devices calculate the HMAC of their own device keys and a comma-separated sorted list of the key IDs that they wish the other user to verify, using SHA-256 as the hash function. HMAC is defined in [RFC 2104](https://tools.ietf.org/html/rfc2104). The key for the HMAC is different for each item and is calculated by generating 32 bytes (256 bits) using [the key verification HKDF](#hkdf-calculation). -18. Alice's device sends Bob's device an `m.key.verification.mac` +16. Alice's device sends Bob's device an `m.key.verification.mac` message containing the MAC of Alice's device keys and the MAC of her key IDs to be verified. Bob's device does the same for Bob's device keys and key IDs concurrently with Alice. -19. When the other device receives the `m.key.verification.mac` message, +17. When the other device receives the `m.key.verification.mac` message, the device calculates the HMAC of its copies of the other device's keys given in the message, as well as the HMAC of the comma-separated, sorted, list of key IDs in the message. The device compares these with the HMAC values given in the message, and if everything matches then the device keys are verified. +18. Alice and Bob's devices send `m.key.verification.done` messages to complete + the verification. The wire protocol looks like the following between Alice and Bob's devices: From f9dce3dfedb739d1437907620aa55e727131a734 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 27 Apr 2021 18:54:22 -0400 Subject: [PATCH 48/63] Add spec for verification by QR codes. --- .../modules/end_to_end_encryption.md | 125 +++++++++++++++++- ...y.verification.start$m.reciprocate.v1.yaml | 44 ++++++ 2 files changed, 167 insertions(+), 2 deletions(-) create mode 100644 data/event-schemas/schema/m.key.verification.start$m.reciprocate.v1.yaml diff --git a/content/client-server-api/modules/end_to_end_encryption.md b/content/client-server-api/modules/end_to_end_encryption.md index 16cd3178..b5388003 100644 --- a/content/client-server-api/modules/end_to_end_encryption.md +++ b/content/client-server-api/modules/end_to_end_encryption.md @@ -357,8 +357,8 @@ out-of-band channel: there is no way to do it within Matrix without trusting the administrators of the homeservers. In Matrix, verification works by Alice meeting Bob in person, or -contacting him via some other trusted medium, and using [SAS -Verification](#SAS Verification) to interactively verify Bob's devices. +contacting him via some other trusted medium, and using one of the +verification methods defined below to interactively verify Bob's devices. Alice and Bob may also read aloud their unpadded base64 encoded Ed25519 public key, as returned by `/keys/query`. @@ -986,6 +986,127 @@ user-signing keys. {{% http-api spec="client-server" api="cross_signing" %}} +##### QR codes + +Verifying by QR codes provides a quick way to verify when one of the parties +has a device capable of scanning a QR code. The QR code encodes both parties' +master signing keys as well as a random shared secret that is used to allow +bi-directional verification from a single scan. + +To advertise the ability to show a QR code, clients use the names +`m.qr_code.show.v1` and `m.reciprocate.v1` in the `methods` fields of the +`m.key.verification.request` and `m.key.verification.ready` events. To +advertise the ability to scan a QR code, clients use the names +`m.qr_code.scan.v1` and `m.reciprocate.v1` in the `methods` fields of the +`m.key.verification.request` and `m.key.verification.ready` events. + +The process between Alice and Bob verifying each other would be: + +1. Alice and Bob meet in person, and want to verify each other's keys. +2. Alice and Bob begin a key verification using the key verification + framework as described above. +3. Alice's client displays a QR code that Bob is able to scan if Bob's client + indicated the ability to scan, an option to scan Bob's QR code if her client + is able to scan. Bob's client prompts displays a QR code that Alice can + scan if Alice's client indicated the ability to scan, and an option to scan + Alice's QR code if his client is able to scan. The format for the QR code + is described below. +5. Alice scans Bob's QR code. +6. Alice's device ensures that the keys encoded in the QR code match the + expected values for the keys. If not, Alice's device displays an error + message indicating that the code is incorrect, and sends a + `m.key.verification.cancel` message to Bob's device. + + Otherwise, at this point: + - Alice's device has now verified Bob's key, and + - Alice's device knows that Bob has the correct key for her. + + Thus for Bob to verify Alice's key, Alice needs to tell Bob that he has the + right key. +7. Alice's device displays a message saying that the verification was + successful. This message tells Alice that she has the right key for Bob, + and tells Bob that he has the right key for Alice. +8. Alice's device sends an `m.key.verification.start` message with `method` set + to `m.reciprocate.v1` to Bob (see below). The message includes the shared + secret from the QR code. This signals to Bob's device that Alice has + scanned Bob's QR code. + + This message is merely a signal for Bob's device to proceed to the next + step, and is not used for verification purposes. +9. Upon receipt of the `m.key.verification.start` message, Bob's device ensures + that the shared secret matches. + + If the shared secret does not match, it should display an error message + indicating that an attack was attempted. (This does not affect Alice's + verification of Bob's keys.) + + If the shared secret does match, it asks Bob to confirm that Alice + has scanned the QR code. +10. Bob sees Alice's device confirm that the key matches, and presses the button + on his device to indicate that Alice's key is verified. + + Bob's verification of Alice's key hinges on Alice telling Bob the result of + her scan. Since the QR code includes what Bob thinks Alice's key is, + Alice's device can check whether Bob has the right key for her. Alice has + no motivation to lie about the result, as getting Bob to trust an incorrect + key would only affect communications between herself and Bob. Thus Alice + telling Bob that the code was scanned successfully is sufficient for Bob to + trust Alice's key, under the assumption that this communication is done + over a trusted medium (such as in-person). +11. Both devices send an `m.key.verification.done` message. + +###### QR code format + +The QR codes to be displayed and scanned using this format will encode binary +strings in the general form: + +- the ASCII string "MATRIX" +- one byte indicating the QR code version (must be `0x02`) +- one byte indicating the QR code verification mode. May be one of the + following values: + - `0x00` verifying another user with cross-signing + - `0x01` self-verifying in which the current device does trust the master key + - `0x02` self-verifying in which the current device does not yet trust the + master key +- the event ID or `transaction_id` of the associated verification + request event, encoded as: + - two bytes in network byte order (big-endian) indicating the length in + bytes of the ID as a UTF-8 string + - the ID as a UTF-8 string +- the first key, as 32 bytes. The key to use depends on the mode field: + - if `0x00` or `0x01`, then the current user's own master cross-signing public key + - if `0x02`, then the current device's device key +- the second key, as 32 bytes. The key to use depends on the mode field: + - if `0x00`, then what the device thinks the other user's master + cross-signing key is + - if `0x01`, then what the device thinks the other device's device key is + - if `0x02`, then what the device thinks the user's master cross-signing key + is +- a random shared secret, as a byte string. It is suggested to use a secret + that is about 8 bytes long. Note: as we do not share the length of the + secret, and it is not a fixed size, clients will just use the remainder of + binary string as the shared secret. + +For example, if Alice displays a QR code encoding the following binary string: + +``` + "MATRIX" |ver|mode| len | event ID + 4D 41 54 52 49 58 02 00 00 2D 21 41 42 43 44 ... +| user's cross-signing key | other user's cross-signing key | shared secret + 00 01 02 03 04 05 06 07 ... 10 11 12 13 14 15 16 17 ... 20 21 22 23 24 25 26 27 +``` + +this indicates that Alice is verifying another user (say Bob), in response to +the request from event "$ABCD...", her cross-signing key is +`0001020304050607...` (which is "AAECAwQFBg..." in base64), she thinks that +Bob's cross-signing key is `1011121314151617...` (which is "EBESExQVFh..." in +base64), and the shared secret is `2021222324252627` (which is "ICEiIyQlJic" in +base64). + +###### Verification messages specific to QR codes + +{{% event event="m.key.verification.start$m.reciprocate.v1" %}} + #### Sharing keys between devices If Bob has an encrypted conversation with Alice on his computer, and diff --git a/data/event-schemas/schema/m.key.verification.start$m.reciprocate.v1.yaml b/data/event-schemas/schema/m.key.verification.start$m.reciprocate.v1.yaml new file mode 100644 index 00000000..a60711b3 --- /dev/null +++ b/data/event-schemas/schema/m.key.verification.start$m.reciprocate.v1.yaml @@ -0,0 +1,44 @@ +--- +allOf: + - $ref: core-event-schema/event.yaml + +description: |- + Begins a key verification process using the `m.reciprocate.v1` method, after + scanning a QR code. +properties: + content: + properties: + from_device: + type: string + description: |- + The device ID which is initiating the process. + transaction_id: + type: string + description: |- + Required when sent as a to-device message. An opaque identifier for + the verification process. Must be unique with respect to the devices + involved. Must be the same as the `transaction_id` given in the + `m.key.verification.request` if this process is originating from a + request. + method: + type: string + enum: ["m.reciprocate.v1"] + description: |- + The verification method to use. + secret: + type: string + description: |- + The shared secret from the QR code, encoded using unpadded base64. + m.relates_to: + allOf: + - $ref: m.key.verification.m.relates_to.yaml + required: + - from_device + - method + - secret + type: object + type: + enum: + - m.key.verification.start + type: string +type: object From bb06dbdb2ae990295663a48ee10b688059bd69d9 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 27 Apr 2021 17:17:48 -0400 Subject: [PATCH 49/63] Add information about using SSSS for cross-signing and key backup. --- .../modules/end_to_end_encryption.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/content/client-server-api/modules/end_to_end_encryption.md b/content/client-server-api/modules/end_to_end_encryption.md index 16cd3178..32a96692 100644 --- a/content/client-server-api/modules/end_to_end_encryption.md +++ b/content/client-server-api/modules/end_to_end_encryption.md @@ -944,6 +944,13 @@ example, if Alice and Bob verify each other using SAS, Alice's `mac` property. Servers therefore must ensure that device IDs will not collide with cross-signing public keys. +The cross-signing private keys can be stored on the server or shared with other +devices using the [Secrets](#secrets) module. When doing so, the master, +user-signing, and self-signing keys are identified using the names +`m.cross_signing.master`, `m.cross_signing.user_signing`, and +`m.cross_signing.self_signing`, respectively, and the keys are base64-encoded +before being encrypted. + ###### Key and signature security A user's master key could allow an attacker to impersonate that user to @@ -1083,6 +1090,11 @@ as follows: When reading in a recovery key, clients must disregard whitespace, and perform the reverse of steps 1 through 3. +The recovery key can also be stored on the server or shared with other devices +using the [Secrets](#secrets) module. When doing so, it is identified using the +name `m.megolm_backup.v1`, and the key is base64-encoded before being +encrypted. + ###### Backup algorithm: `m.megolm_backup.v1.curve25519-aes-sha2` When a backup is created with the `algorithm` set to From c3a234843baa50bba04993199eafc2a65b87c270 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 27 Apr 2021 21:02:34 -0400 Subject: [PATCH 50/63] add changelog --- changelogs/client_server/newsfragments/3150.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/3150.feature diff --git a/changelogs/client_server/newsfragments/3150.feature b/changelogs/client_server/newsfragments/3150.feature new file mode 100644 index 00000000..37331065 --- /dev/null +++ b/changelogs/client_server/newsfragments/3150.feature @@ -0,0 +1 @@ +Add key verification using in-room messages as per [MSC2241](https://github.com/matrix-org/matrix-doc/pull/2241). From ca37ada9e25ace41b6475c0cf0d90ff581ce2c41 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 27 Apr 2021 22:04:35 -0400 Subject: [PATCH 51/63] Document Single SSSS. --- content/client-server-api/modules/secrets.md | 24 +++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/content/client-server-api/modules/secrets.md b/content/client-server-api/modules/secrets.md index b4ae8c02..897ea196 100644 --- a/content/client-server-api/modules/secrets.md +++ b/content/client-server-api/modules/secrets.md @@ -42,7 +42,7 @@ passphrases](#deriving-keys-from-passphrases). | Parameter | Type | Description |------------|-----------|-------------------------------------------------------------------------------------------------------------------------------------| -| name | string | **Required.** The name of the key. | +| name | string | Optional. The name of the key. If not given, the client may use a generic name such as "Unnamed key", or "Default key" if the key is marked as the default key (see below). | | algorithm | string | **Required.** The encryption algorithm to be used for this key. Currently, only `m.secret_storage.v1.aes-hmac-sha2` is supported. | | passphrase | string | See [deriving keys from passphrases](#deriving-keys-from-passphrases) section for a description of this property. | @@ -56,6 +56,18 @@ will be used to encrypt all secrets that the user would expect to be available on all their clients. Unless the user specifies otherwise, clients will try to use the default key to decrypt secrets. +Clients that want to present a simplified interface to users by not supporting +multiple keys should use the default key if one is specified. If not default +key is specified, the client may behave as if there is no key is present at +all. When such a client creates a key, it should mark that key as being the +default key. + +`DefaultKey` + +| Parameter | Type | Description +|------------|-----------|------------------------------------------| +| key | string | **Required.** The ID of the default key. | + ##### Secret storage Encrypted data is stored in the user's account\_data using the event @@ -118,6 +130,16 @@ and the key descriptions for the keys would be: } ``` +If `key_id_1` is the default key, then we also have: + +`m.secret_storage.default_key`: + +``` +{ + "key": "key_id_1" +} +``` + ###### `m.secret_storage.v1.aes-hmac-sha2` Secrets encrypted using the `m.secret_storage.v1.aes-hmac-sha2` From c85f98bdab94b3d27f85da22b5ff47a6297975d4 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 27 Apr 2021 20:56:18 -0400 Subject: [PATCH 52/63] add changelog --- changelogs/client_server/newsfragments/3149.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/3149.feature diff --git a/changelogs/client_server/newsfragments/3149.feature b/changelogs/client_server/newsfragments/3149.feature new file mode 100644 index 00000000..2a85b47f --- /dev/null +++ b/changelogs/client_server/newsfragments/3149.feature @@ -0,0 +1 @@ +Add key verification method using QR codes ([MSC1544](https://github.com/matrix-org/matrix-doc/pull/1544)). From 21fa486b3b1b99ddbe404ae00b741b564eb15739 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 27 Apr 2021 17:24:04 -0400 Subject: [PATCH 53/63] add changelog --- changelogs/client_server/newsfragments/3147.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/3147.feature diff --git a/changelogs/client_server/newsfragments/3147.feature b/changelogs/client_server/newsfragments/3147.feature new file mode 100644 index 00000000..21017aaf --- /dev/null +++ b/changelogs/client_server/newsfragments/3147.feature @@ -0,0 +1 @@ +Add information about using SSSS for cross-signing and key backup. From 4b40ecc53d0cc8e05c1b8a5193b65335f3354e5b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 27 Apr 2021 09:28:21 -0600 Subject: [PATCH 54/63] Update i18n --- data-definitions/sas-emoji.json | 68 ++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/data-definitions/sas-emoji.json b/data-definitions/sas-emoji.json index 3ec3c6b2..0b213d9d 100644 --- a/data-definitions/sas-emoji.json +++ b/data-definitions/sas-emoji.json @@ -27,6 +27,7 @@ "sr": "пас", "sv": "Hund", "szl": null, + "tzm": "Aydi", "uk": "Пес", "zh_Hans": "狗" } @@ -59,6 +60,7 @@ "sr": "мачка", "sv": "Katt", "szl": null, + "tzm": "Amuc", "uk": "Кіт", "zh_Hans": "猫" } @@ -91,6 +93,7 @@ "sr": "лав", "sv": "Lejon", "szl": null, + "tzm": "Izem", "uk": "Лев", "zh_Hans": "狮子" } @@ -123,6 +126,7 @@ "sr": "коњ", "sv": "Häst", "szl": null, + "tzm": "Ayyis", "uk": "Кінь", "zh_Hans": "马" } @@ -155,6 +159,7 @@ "sr": "једнорог", "sv": "Enhörning", "szl": null, + "tzm": null, "uk": "Єдиноріг", "zh_Hans": "独角兽" } @@ -187,6 +192,7 @@ "sr": "прасе", "sv": "Gris", "szl": null, + "tzm": "Ilef", "uk": "Свиня", "zh_Hans": "猪" } @@ -219,6 +225,7 @@ "sr": "слон", "sv": "Elefant", "szl": null, + "tzm": "Ilu", "uk": "Слон", "zh_Hans": "大象" } @@ -251,6 +258,7 @@ "sr": "зец", "sv": "Kanin", "szl": null, + "tzm": "Agnin", "uk": "Кріль", "zh_Hans": "兔子" } @@ -283,6 +291,7 @@ "sr": "панда", "sv": "Panda", "szl": null, + "tzm": null, "uk": "Панда", "zh_Hans": "熊猫" } @@ -315,6 +324,7 @@ "sr": "петао", "sv": "Tupp", "szl": null, + "tzm": "Ayaẓiḍ", "uk": "Когут", "zh_Hans": "公鸡" } @@ -347,6 +357,7 @@ "sr": "пингвин", "sv": "Pingvin", "szl": null, + "tzm": null, "uk": "Пінгвін", "zh_Hans": "企鹅" } @@ -379,6 +390,7 @@ "sr": "корњача", "sv": "Sköldpadda", "szl": null, + "tzm": "Ifker", "uk": "Черепаха", "zh_Hans": "乌龟" } @@ -411,6 +423,7 @@ "sr": "риба", "sv": "Fisk", "szl": null, + "tzm": "Aselm", "uk": "Риба", "zh_Hans": "鱼" } @@ -443,6 +456,7 @@ "sr": "октопод", "sv": "Bläckfisk", "szl": null, + "tzm": null, "uk": "Восьминіг", "zh_Hans": "章鱼" } @@ -475,6 +489,7 @@ "sr": "лептир", "sv": "Fjäril", "szl": null, + "tzm": null, "uk": "Метелик", "zh_Hans": "蝴蝶" } @@ -507,6 +522,7 @@ "sr": "цвет", "sv": "Blomma", "szl": null, + "tzm": null, "uk": "Квітка", "zh_Hans": "花" } @@ -539,6 +555,7 @@ "sr": "дрво", "sv": "Träd", "szl": null, + "tzm": "Aseklu", "uk": "Дерево", "zh_Hans": "树" } @@ -571,6 +588,7 @@ "sr": "кактус", "sv": "Kaktus", "szl": null, + "tzm": null, "uk": "Кактус", "zh_Hans": "仙人掌" } @@ -603,6 +621,7 @@ "sr": "печурка", "sv": "Svamp", "szl": null, + "tzm": "Agursel", "uk": "Гриб", "zh_Hans": "蘑菇" } @@ -635,6 +654,7 @@ "sr": "глобус", "sv": "Jordklot", "szl": null, + "tzm": null, "uk": "Глобус", "zh_Hans": "地球" } @@ -667,6 +687,7 @@ "sr": "месец", "sv": "Måne", "szl": null, + "tzm": "Ayyur", "uk": "Місяць", "zh_Hans": "月亮" } @@ -699,6 +720,7 @@ "sr": "облак", "sv": "Moln", "szl": null, + "tzm": null, "uk": "Хмара", "zh_Hans": "云" } @@ -731,6 +753,7 @@ "sr": "ватра", "sv": "Eld", "szl": null, + "tzm": "Timessi", "uk": "Вогонь", "zh_Hans": "火" } @@ -763,6 +786,7 @@ "sr": "банана", "sv": "Banan", "szl": null, + "tzm": "Tabanant", "uk": "Банан", "zh_Hans": "香蕉" } @@ -795,6 +819,7 @@ "sr": "јабука", "sv": "Äpple", "szl": null, + "tzm": "Tadeffuyt", "uk": "Яблуко", "zh_Hans": "苹果" } @@ -827,6 +852,7 @@ "sr": "јагода", "sv": "Jordgubbe", "szl": null, + "tzm": null, "uk": "Полуниця", "zh_Hans": "草莓" } @@ -859,6 +885,7 @@ "sr": "кукуруз", "sv": "Majs", "szl": null, + "tzm": null, "uk": "Кукурудза", "zh_Hans": "玉米" } @@ -891,6 +918,7 @@ "sr": "пица", "sv": "Pizza", "szl": null, + "tzm": null, "uk": "Піца", "zh_Hans": "披萨" } @@ -923,6 +951,7 @@ "sr": "торта", "sv": "Tårta", "szl": null, + "tzm": null, "uk": "Пиріг", "zh_Hans": "蛋糕" } @@ -955,6 +984,7 @@ "sr": "срце", "sv": "Hjärta", "szl": null, + "tzm": "Ul", "uk": "Серце", "zh_Hans": "心" } @@ -987,6 +1017,7 @@ "sr": "смајли", "sv": "Smiley", "szl": null, + "tzm": null, "uk": "Посмішка", "zh_Hans": "笑脸" } @@ -1019,6 +1050,7 @@ "sr": "робот", "sv": "Robot", "szl": null, + "tzm": "Aṛubu", "uk": "Робот", "zh_Hans": "机器人" } @@ -1038,7 +1070,7 @@ "es": "Sombrero", "et": "Kübar", "fi": "Hattu", - "fr": "Châpeau", + "fr": "Chapeau", "hr": "kapa", "it": "Cappello", "ja": "帽子", @@ -1051,6 +1083,7 @@ "sr": "шешир", "sv": "Hatt", "szl": null, + "tzm": "Taraza", "uk": "Капелюх", "zh_Hans": "帽子" } @@ -1083,6 +1116,7 @@ "sr": "наочаре", "sv": "Glasögon", "szl": null, + "tzm": null, "uk": "Окуляри", "zh_Hans": "眼镜" } @@ -1115,6 +1149,7 @@ "sr": "кључ", "sv": "Skruvnyckel", "szl": null, + "tzm": null, "uk": "Гайковий ключ", "zh_Hans": "扳手" } @@ -1147,6 +1182,7 @@ "sr": "деда Мраз", "sv": "Tomte", "szl": null, + "tzm": null, "uk": "Санта Клаус", "zh_Hans": "圣诞老人" } @@ -1166,7 +1202,7 @@ "es": "Pulgar arriba", "et": "Pöidlad püsti", "fi": "Peukalo ylös", - "fr": "Pouce en l'air", + "fr": "Pouce en l’air", "hr": "palac gore", "it": "Pollice alzato", "ja": "いいね", @@ -1179,6 +1215,7 @@ "sr": "палчић горе", "sv": "Tummen upp", "szl": null, + "tzm": null, "uk": "Великий палець вгору", "zh_Hans": "赞" } @@ -1211,6 +1248,7 @@ "sr": "кишобран", "sv": "Paraply", "szl": null, + "tzm": null, "uk": "Парасолька", "zh_Hans": "伞" } @@ -1243,6 +1281,7 @@ "sr": "пешчаник", "sv": "Timglas", "szl": null, + "tzm": null, "uk": "Пісковий годинник", "zh_Hans": "沙漏" } @@ -1275,6 +1314,7 @@ "sr": "сат", "sv": "Klocka", "szl": null, + "tzm": null, "uk": "Годинник", "zh_Hans": "时钟" } @@ -1307,6 +1347,7 @@ "sr": "поклон", "sv": "Present", "szl": null, + "tzm": null, "uk": "Подарунок", "zh_Hans": "礼物" } @@ -1339,6 +1380,7 @@ "sr": "сијалица", "sv": "Lampa", "szl": null, + "tzm": null, "uk": "Лампочка", "zh_Hans": "灯泡" } @@ -1371,6 +1413,7 @@ "sr": "књига", "sv": "Bok", "szl": null, + "tzm": "Adlis", "uk": "Книга", "zh_Hans": "书" } @@ -1403,6 +1446,7 @@ "sr": "оловка", "sv": "Penna", "szl": null, + "tzm": null, "uk": "Олівець", "zh_Hans": "铅笔" } @@ -1435,6 +1479,7 @@ "sr": "спајалица", "sv": "Gem", "szl": null, + "tzm": null, "uk": "Спиначка", "zh_Hans": "回形针" } @@ -1467,6 +1512,7 @@ "sr": "маказе", "sv": "Sax", "szl": null, + "tzm": null, "uk": "Ножиці", "zh_Hans": "剪刀" } @@ -1499,6 +1545,7 @@ "sr": "катанац", "sv": "Lås", "szl": null, + "tzm": null, "uk": "Замок", "zh_Hans": "锁" } @@ -1531,6 +1578,7 @@ "sr": "кључ", "sv": "Nyckel", "szl": null, + "tzm": "Tasarut", "uk": "Ключ", "zh_Hans": "钥匙" } @@ -1563,6 +1611,7 @@ "sr": "чекић", "sv": "Hammare", "szl": null, + "tzm": null, "uk": "Молоток", "zh_Hans": "锤子" } @@ -1595,6 +1644,7 @@ "sr": "телефон", "sv": "Telefon", "szl": null, + "tzm": "Atilifun", "uk": "Телефон", "zh_Hans": "电话" } @@ -1627,6 +1677,7 @@ "sr": "застава", "sv": "Flagga", "szl": null, + "tzm": "Acenyal", "uk": "Прапор", "zh_Hans": "旗帜" } @@ -1659,6 +1710,7 @@ "sr": "воз", "sv": "Tåg", "szl": null, + "tzm": null, "uk": "Потяг", "zh_Hans": "火车" } @@ -1691,6 +1743,7 @@ "sr": "бицикл", "sv": "Cykel", "szl": null, + "tzm": null, "uk": "Велосипед", "zh_Hans": "自行车" } @@ -1723,6 +1776,7 @@ "sr": "авион", "sv": "Flygplan", "szl": null, + "tzm": null, "uk": "Літак", "zh_Hans": "飞机" } @@ -1755,6 +1809,7 @@ "sr": "ракета", "sv": "Raket", "szl": null, + "tzm": null, "uk": "Ракета", "zh_Hans": "火箭" } @@ -1787,6 +1842,7 @@ "sr": "пехар", "sv": "Trofé", "szl": null, + "tzm": null, "uk": "Приз", "zh_Hans": "奖杯" } @@ -1819,6 +1875,7 @@ "sr": "лопта", "sv": "Boll", "szl": null, + "tzm": "Tcama", "uk": "М'яч", "zh_Hans": "球" } @@ -1851,6 +1908,7 @@ "sr": "гитара", "sv": "Gitarr", "szl": null, + "tzm": "Agiṭaṛ", "uk": "Гітара", "zh_Hans": "吉他" } @@ -1883,6 +1941,7 @@ "sr": "труба", "sv": "Trumpet", "szl": null, + "tzm": null, "uk": "Труба", "zh_Hans": "喇叭" } @@ -1915,6 +1974,7 @@ "sr": "звоно", "sv": "Bjällra", "szl": null, + "tzm": null, "uk": "Дзвін", "zh_Hans": "铃铛" } @@ -1947,6 +2007,7 @@ "sr": "сидро", "sv": "Ankare", "szl": null, + "tzm": null, "uk": "Якір", "zh_Hans": "锚" } @@ -1979,6 +2040,7 @@ "sr": "слушалице", "sv": "Hörlurar", "szl": null, + "tzm": null, "uk": "Навушники", "zh_Hans": "耳机" } @@ -2011,6 +2073,7 @@ "sr": "фасцикла", "sv": "Mapp", "szl": null, + "tzm": "Asdaw", "uk": "Тека", "zh_Hans": "文件夹" } @@ -2043,6 +2106,7 @@ "sr": "чиода", "sv": "Häftstift", "szl": null, + "tzm": null, "uk": "Кнопка", "zh_Hans": "图钉" } From 7a960375cc611b983e31cb00fef84cb4532b4685 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 28 Apr 2021 15:52:20 -0400 Subject: [PATCH 55/63] Update content/client-server-api/modules/end_to_end_encryption.md Co-authored-by: Travis Ralston --- content/client-server-api/modules/end_to_end_encryption.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/client-server-api/modules/end_to_end_encryption.md b/content/client-server-api/modules/end_to_end_encryption.md index 332fb55a..48fe6a75 100644 --- a/content/client-server-api/modules/end_to_end_encryption.md +++ b/content/client-server-api/modules/end_to_end_encryption.md @@ -585,7 +585,7 @@ The process between Alice and Bob verifying each other would be: 2. Alice and Bob begin a key verification using the key verification framework as described above. 3. Alice's device sends Bob's device an `m.key.verification.start` - message. Alice's client ensures it has a copy of Bob's device key. + message. Alice's device ensures it has a copy of Bob's device key. 4. Bob's device receives the message and selects a key agreement protocol, hash algorithm, message authentication code, and SAS method supported by Alice's device. From b2cb2a3c20102ec646d54017ee8376b905cbcc13 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 27 Apr 2021 22:07:57 -0400 Subject: [PATCH 56/63] add changelog --- changelogs/client_server/newsfragments/3151.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/3151.feature diff --git a/changelogs/client_server/newsfragments/3151.feature b/changelogs/client_server/newsfragments/3151.feature new file mode 100644 index 00000000..a6aa98e9 --- /dev/null +++ b/changelogs/client_server/newsfragments/3151.feature @@ -0,0 +1 @@ +Document how clients can simplify usage of Secure Secret Storage ([MSC2874](https://github.com/uhoreg/matrix-doc/pull/new/single_ssss_spec)). From 1a1f01234d98d5ae49b767ac14bd066b087101aa Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 28 Apr 2021 15:59:55 -0400 Subject: [PATCH 57/63] Apply suggestions from code review Co-authored-by: Travis Ralston --- .../modules/end_to_end_encryption.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/content/client-server-api/modules/end_to_end_encryption.md b/content/client-server-api/modules/end_to_end_encryption.md index b5388003..db689ad0 100644 --- a/content/client-server-api/modules/end_to_end_encryption.md +++ b/content/client-server-api/modules/end_to_end_encryption.md @@ -999,6 +999,9 @@ To advertise the ability to show a QR code, clients use the names advertise the ability to scan a QR code, clients use the names `m.qr_code.scan.v1` and `m.reciprocate.v1` in the `methods` fields of the `m.key.verification.request` and `m.key.verification.ready` events. +Clients that support both showing and scanning QR codes would advertise +`m.qr_code.show.v1`, `m.qr_code.scan.v1`, and `m.reciprocate.v1` as +methods. The process between Alice and Bob verifying each other would be: @@ -1010,7 +1013,9 @@ The process between Alice and Bob verifying each other would be: is able to scan. Bob's client prompts displays a QR code that Alice can scan if Alice's client indicated the ability to scan, and an option to scan Alice's QR code if his client is able to scan. The format for the QR code - is described below. + is described below. Other options, like starting SAS Emoji verification, + can be presented alongside the QR code if the devices have appropriate + support. 5. Alice scans Bob's QR code. 6. Alice's device ensures that the keys encoded in the QR code match the expected values for the keys. If not, Alice's device displays an error @@ -1024,8 +1029,11 @@ The process between Alice and Bob verifying each other would be: Thus for Bob to verify Alice's key, Alice needs to tell Bob that he has the right key. 7. Alice's device displays a message saying that the verification was - successful. This message tells Alice that she has the right key for Bob, - and tells Bob that he has the right key for Alice. + successful because the QR code's keys will have matched the keys + expected for Bob. Bob's device hasn't had a chance to verify Alice's + keys yet so wouldn't show the same message. Bob will know that + he has the right key for Alice because Alice's device will have shown + this message, as otherwise the verification would be cancelled. 8. Alice's device sends an `m.key.verification.start` message with `method` set to `m.reciprocate.v1` to Bob (see below). The message includes the shared secret from the QR code. This signals to Bob's device that Alice has @@ -1060,9 +1068,9 @@ The process between Alice and Bob verifying each other would be: The QR codes to be displayed and scanned using this format will encode binary strings in the general form: -- the ASCII string "MATRIX" +- the ASCII string `MATRIX` - one byte indicating the QR code version (must be `0x02`) -- one byte indicating the QR code verification mode. May be one of the +- one byte indicating the QR code verification mode. Should be one of the following values: - `0x00` verifying another user with cross-signing - `0x01` self-verifying in which the current device does trust the master key From fa6cc8a1ff46ea80f567627d5cba5a634b44a51e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 28 Apr 2021 19:50:13 -0600 Subject: [PATCH 58/63] Add knocking to the spec Spec for https://github.com/matrix-org/matrix-doc/pull/2998 Spec for https://github.com/matrix-org/matrix-doc/pull/2403 This deliberately does not help towards fixing https://github.com/matrix-org/matrix-doc/issues/3153 in order to remain consistent with prior room versions, and to keep the diff smaller on this change. A future change will address room version legibility. --- content/_index.md | 9 +- content/client-server-api/_index.md | 166 +++++---- content/rooms/_index.md | 1 + content/rooms/v7.md | 52 +++ content/server-server-api.md | 44 ++- .../definitions/public_rooms_response.yaml | 12 +- data/api/client-server/knocking.yaml | 124 +++++++ data/api/client-server/sync.yaml | 44 ++- data/api/server-server/knocks.yaml | 321 ++++++++++++++++++ data/api/server-server/public_rooms.yaml | 12 +- .../examples/knock_room_state.json | 18 + .../m.room.member$knock_room_state.yaml | 15 + .../schema/m.room.join_rules.yaml | 11 +- data/event-schemas/schema/m.room.member.yaml | 35 +- static/diagrams/README.md | 17 + static/diagrams/membership.drawio | 1 + static/diagrams/membership.png | Bin 0 -> 28770 bytes 17 files changed, 779 insertions(+), 103 deletions(-) create mode 100644 content/rooms/v7.md create mode 100644 data/api/client-server/knocking.yaml create mode 100644 data/api/server-server/knocks.yaml create mode 100644 data/event-schemas/examples/knock_room_state.json create mode 100644 data/event-schemas/examples/m.room.member$knock_room_state.yaml create mode 100644 static/diagrams/README.md create mode 100644 static/diagrams/membership.drawio create mode 100644 static/diagrams/membership.png diff --git a/content/_index.md b/content/_index.md index 845fbc9f..4f7c3051 100644 --- a/content/_index.md +++ b/content/_index.md @@ -327,12 +327,12 @@ sent to the room `!qporfwt:matrix.org`: Federation maintains *shared data structures* per-room between multiple homeservers. The data is split into `message events` and `state events`. -Message events: +Message events: These describe transient 'once-off' activity in a room such as an instant messages, VoIP call setups, file transfers, etc. They generally describe communication activity. -State events: +State events: These describe updates to a given piece of persistent information ('state') related to a room, such as the room's name, topic, membership, participating servers, etc. State is modelled as a lookup table of @@ -505,7 +505,7 @@ stable and unstable periodically for a variety of reasons, including discovered security vulnerabilities and age. Clients should not ask room administrators to upgrade their rooms if the -room is running a stable version. Servers SHOULD use room version 6 as +room is running a stable version. Servers SHOULD use **room version 6** as the default room version when creating new rooms. The available room versions are: @@ -522,10 +522,11 @@ The available room versions are: signing key validity periods. - [Version 6](/rooms/v6) - **Stable**. Alters several authorization rules for events. +- [Version 7](/rooms/v7) - **Stable**. Introduces knocking. ## Specification Versions -The specification for each API is versioned in the form `rX.Y.Z`. +The specification for each API is versioned in the form `rX.Y.Z`. - A change to `X` reflects a breaking change: a client implemented against `r1.0.0` may need changes to work with a server which supports (only) `r2.0.0`. diff --git a/content/client-server-api/_index.md b/content/client-server-api/_index.md index a5964fe7..a9103c7a 100644 --- a/content/client-server-api/_index.md +++ b/content/client-server-api/_index.md @@ -68,118 +68,118 @@ request being made was invalid. The common error codes are: -`M_FORBIDDEN` +`M_FORBIDDEN` Forbidden access, e.g. joining a room without permission, failed login. -`M_UNKNOWN_TOKEN` +`M_UNKNOWN_TOKEN` The access token specified was not recognised. An additional response parameter, `soft_logout`, might be present on the response for 401 HTTP status codes. See [the soft logout section](#soft-logout) for more information. -`M_MISSING_TOKEN` +`M_MISSING_TOKEN` No access token was specified for the request. -`M_BAD_JSON` +`M_BAD_JSON` Request contained valid JSON, but it was malformed in some way, e.g. missing required keys, invalid values for keys. -`M_NOT_JSON` +`M_NOT_JSON` Request did not contain valid JSON. -`M_NOT_FOUND` +`M_NOT_FOUND` No resource was found for this request. -`M_LIMIT_EXCEEDED` +`M_LIMIT_EXCEEDED` Too many requests have been sent in a short period of time. Wait a while then try again. -`M_UNKNOWN` +`M_UNKNOWN` An unknown error has occurred. Other error codes the client might encounter are: -`M_UNRECOGNIZED` +`M_UNRECOGNIZED` The server did not understand the request. -`M_UNAUTHORIZED` +`M_UNAUTHORIZED` The request was not correctly authorized. Usually due to login failures. -`M_USER_DEACTIVATED` +`M_USER_DEACTIVATED` The user ID associated with the request has been deactivated. Typically for endpoints that prove authentication, such as `/login`. -`M_USER_IN_USE` +`M_USER_IN_USE` Encountered when trying to register a user ID which has been taken. -`M_INVALID_USERNAME` +`M_INVALID_USERNAME` Encountered when trying to register a user ID which is not valid. -`M_ROOM_IN_USE` +`M_ROOM_IN_USE` Sent when the room alias given to the `createRoom` API is already in use. -`M_INVALID_ROOM_STATE` +`M_INVALID_ROOM_STATE` Sent when the initial state given to the `createRoom` API is invalid. -`M_THREEPID_IN_USE` +`M_THREEPID_IN_USE` Sent when a threepid given to an API cannot be used because the same threepid is already in use. -`M_THREEPID_NOT_FOUND` +`M_THREEPID_NOT_FOUND` Sent when a threepid given to an API cannot be used because no record matching the threepid was found. -`M_THREEPID_AUTH_FAILED` +`M_THREEPID_AUTH_FAILED` Authentication could not be performed on the third party identifier. -`M_THREEPID_DENIED` +`M_THREEPID_DENIED` The server does not permit this third party identifier. This may happen if the server only permits, for example, email addresses from a particular domain. -`M_SERVER_NOT_TRUSTED` +`M_SERVER_NOT_TRUSTED` The client's request used a third party server, e.g. identity server, that this server does not trust. -`M_UNSUPPORTED_ROOM_VERSION` +`M_UNSUPPORTED_ROOM_VERSION` The client's request to create a room used a room version that the server does not support. -`M_INCOMPATIBLE_ROOM_VERSION` +`M_INCOMPATIBLE_ROOM_VERSION` The client attempted to join a room that has a version the server does not support. Inspect the `room_version` property of the error response for the room's version. -`M_BAD_STATE` +`M_BAD_STATE` The state change requested cannot be performed, such as attempting to unban a user who is not banned. -`M_GUEST_ACCESS_FORBIDDEN` +`M_GUEST_ACCESS_FORBIDDEN` The room or resource does not permit guests to access it. -`M_CAPTCHA_NEEDED` +`M_CAPTCHA_NEEDED` A Captcha is required to complete the request. -`M_CAPTCHA_INVALID` +`M_CAPTCHA_INVALID` The Captcha provided did not match what was expected. -`M_MISSING_PARAM` +`M_MISSING_PARAM` A required parameter was missing from the request. -`M_INVALID_PARAM` +`M_INVALID_PARAM` A parameter that was specified has the wrong value. For example, the server expected an integer and instead received a string. -`M_TOO_LARGE` +`M_TOO_LARGE` The request or entity was too large. -`M_EXCLUSIVE` +`M_EXCLUSIVE` The resource being requested is reserved by an application service, or the application service making the request has not created the resource. -`M_RESOURCE_LIMIT_EXCEEDED` +`M_RESOURCE_LIMIT_EXCEEDED` The request cannot be completed because the homeserver has reached a resource limit imposed on it. For example, a homeserver held in a shared hosting environment may reach a resource limit if it starts using too @@ -189,7 +189,7 @@ Typically, this error will appear on routes which attempt to modify state (e.g.: sending messages, account data, etc) and not routes which only read state (e.g.: `/sync`, get account data, etc). -`M_CANNOT_LEAVE_SERVER_NOTICE_ROOM` +`M_CANNOT_LEAVE_SERVER_NOTICE_ROOM` The user is unable to reject an invite to join the server notices room. See the [Server Notices](#server-notices) module for more information. @@ -238,23 +238,23 @@ time. In this section, the following terms are used with specific meanings: -`PROMPT` +`PROMPT` Retrieve the specific piece of information from the user in a way which fits within the existing client user experience, if the client is inclined to do so. Failure can take place instead if no good user experience for this is possible at this point. -`IGNORE` +`IGNORE` Stop the current auto-discovery mechanism. If no more auto-discovery mechanisms are available, then the client may use other methods of determining the required parameters, such as prompting the user, or using default values. -`FAIL_PROMPT` +`FAIL_PROMPT` Inform the user that auto-discovery failed due to invalid/empty data and `PROMPT` for the parameter. -`FAIL_ERROR` +`FAIL_ERROR` Inform the user that auto-discovery did not return any usable URLs. Do not continue further with the current login process. At this point, valid data was obtained, but no server is available to serve the client. @@ -606,7 +606,7 @@ flow with three stages will resemble the following diagram: #### Authentication types -This specification defines the following auth types: +This specification defines the following auth types: - `m.login.password` - `m.login.recaptcha` - `m.login.sso` @@ -893,7 +893,7 @@ type of identifier being used, and depending on the type, has other fields giving the information required to identify the user as described below. -This specification defines the following identifier types: +This specification defines the following identifier types: - `m.id.user` - `m.id.thirdparty` - `m.id.phone` @@ -1712,7 +1712,7 @@ event also has a `creator` key which contains the user ID of the room creator. It will also generate several other events in order to manage permissions in this room. This includes: -- `m.room.power_levels` : Sets the power levels of users and required power +- `m.room.power_levels` : Sets the power levels of users and required power levels for various actions within the room such as sending events. - `m.room.join_rules` : Whether the room is "invite-only" or not. @@ -1778,6 +1778,8 @@ in that room. There are several states in which a user may be, in relation to a room: - Unrelated (the user cannot send or receive events in the room) +- Knocking (the user has requested to participate in the room, but has + not yet been allowed to) - Invited (the user has been invited to participate in the room, but is not yet participating) - Joined (the user can send and receive events in the room) @@ -1786,49 +1788,28 @@ relation to a room: There is an exception to the requirement that a user join a room before sending events to it: users may send an `m.room.member` event to a room with `content.membership` set to `leave` to reject an invitation if they -have currently been invited to a room but have not joined it. +have currently been invited to a room but have not joined it. The same +applies for retracting knocks on the room that the user sent. Some rooms require that users be invited to it before they can join; others allow anyone to join. Whether a given room is an "invite-only" room is determined by the room config key `m.room.join_rules`. It can have one of the following values: -`public` +`public` This room is free for anyone to join without an invite. -`invite` +`invite` This room can only be joined if you were invited. +`knock` +This room can only be joined if you were invited, and allows anyone to +request an invite to the room. Note that this join rule is only available +to rooms based upon [room version 7](/rooms/v7). + The allowable state transitions of membership are: -``` - /ban - +------------------------------------------------------+ - | | - | +----------------+ +----------------+ | - | | /leave | | | | - | | v v | | - /invite +--------+ +-------+ | | - ------------>| invite |<----------| leave |----+ | | - +--------+ /invite +-------+ | | | - | | ^ | | | - | | | | | | - /join | +---------------+ | | | | - | | /join if | | | | - | | join_rules | | /ban | /unban | - | | public /leave | | | | - v v or | | | | - +------+ /kick | | | | - ------------>| join |-------------------+ | | | - /join +------+ v | | - if | +-----+ | | - join_rules +-------------------------->| ban |-----+ | - public /ban +-----+ | - ^ ^ | - | | | - ----------------------------------------------+ +----------------------+ - /ban -``` +![membership-flow-diagram](/diagrams/membership.png) {{% http-api spec="client-server" api="list_joined_rooms" %}} @@ -1838,14 +1819,51 @@ The allowable state transitions of membership are: {{% http-api spec="client-server" api="joining" %}} +##### Knocking on rooms + + + +If the join rules allow, external users to the room can `/knock` on it to +request permission to join. Users with appropriate permissions within the +room can then approve (`/invite`) or deny (`/kick`, `/ban`, or otherwise +set membership to `leave`) the knock. Knocks can be retracted by calling +`/leave` or otherwise setting membership to `leave`. + +Users who are currently in the room, already invited, or banned cannot +knock on the room. + +To accept another user's knock, the user must have permission to invite +users to the room. To reject another user's knock, the user must have +permission to either kick or ban users (whichever is being performed). +Note that setting another user's membership to `leave` is kicking them. + +The knocking homeserver should assume that an invite to the room means +that the knock was accepted, even if the invite is not explicitly related +to the knock. + +Homeservers are permitted to automatically accept invites as a result of +knocks as they should be aware of the user's intent to join the room. If +the homeserver is not auto-accepting invites (or there was an unrecoverable +problem with accepting it), the invite is expected to be passed down normally +to the client to handle. Clients can expect to see the join event if the +server chose to auto-accept. + +{{% http-api spec="client-server" api="knocking" %}} + #### Leaving rooms A user can leave a room to stop receiving events for that room. A user must have been invited to or have joined the room before they are eligible to leave the room. Leaving a room to which the user has been -invited rejects the invite. Once a user leaves a room, it will no longer -appear in the response to the [`/sync`](/client-server-api/#get_matrixclientr0sync) API unless it is explicitly -requested via a filter with the `include_leave` field set to `true`. +invited rejects the invite, and can retract a knock. Once a user leaves +a room, it will no longer appear in the response to the +[`/sync`](/client-server-api/#get_matrixclientr0sync) API unless it is +explicitly requested via a filter with the `include_leave` field set +to `true`. Whether or not they actually joined the room, if the room is an "invite-only" room the user will need to be re-invited before they can @@ -1853,7 +1871,7 @@ re-join the room. A user can also forget a room which they have left. Rooms which have been forgotten will never appear the response to the [`/sync`](/client-server-api/#get_matrixclientr0sync) API, -until the user re-joins or is re-invited. +until the user re-joins, is re-invited, or knocks. A user may wish to force another user to leave a room. This can be done by 'kicking' the other user. To do so, the user performing the kick MUST diff --git a/content/rooms/_index.md b/content/rooms/_index.md index 92e54bfd..80c688a2 100644 --- a/content/rooms/_index.md +++ b/content/rooms/_index.md @@ -10,3 +10,4 @@ weight: 60 * [Room Version 4](v4) * [Room Version 5](v5) * [Room Version 6](v6) +* [Room Version 7](v7) diff --git a/content/rooms/v7.md b/content/rooms/v7.md new file mode 100644 index 00000000..d9d01317 --- /dev/null +++ b/content/rooms/v7.md @@ -0,0 +1,52 @@ +--- +title: Room Version 7 +type: docs +weight: 60 +--- + +This room version builds on [version 6](/rooms/v6) to introduce knocking +as a possible join rule and membership state. + +## Client considerations + +This is the first room version to support knocking completely. As such, +users will not be able to knock on rooms which are not based off v7. + +## Server implementation components + +{{% boxes/warning %}} +The information contained in this section is strictly for server +implementors. Applications which use the Client-Server API are generally +unaffected by the intricacies contained here. The section above +regarding client considerations is the resource that Client-Server API +use cases should reference. +{{% /boxes/warning %}} + +Room version 7 adds new authorization rules for events to support knocking. +[Room version 6](/rooms/v6) has details of other authorization rule changes, +as do the versions v6 is based upon. + +For checks perfomed upon `m.room.member` events, the following conditions +are added in context: + + If type is `m.room.member`: + + ... + + * If `membership` is `ban`: + + ... + + * If `membership` is `knock`: + + i. If the `join_rule` is anything other than `knock`, reject. + + ii. If `sender` does not match `state_key`, reject. + + iii. If the `sender`'s current membership is not `ban`, `invite`, or `join`, allow. + + iv. Otherwise, reject. + + ... + +The remaining rules are the same as in [room version 6](/rooms/v6#authorization-rules-for-events). diff --git a/content/server-server-api.md b/content/server-server-api.md index 32db92d7..e87e8085 100644 --- a/content/server-server-api.md +++ b/content/server-server-api.md @@ -18,7 +18,7 @@ signatures in HTTP Authorization headers at the HTTP layer. There are three main kinds of communication that occur between homeservers: -Persisted Data Units (PDUs): +Persisted Data Units (PDUs): These events are broadcast from one homeserver to any others that have joined the same room (identified by Room ID). They are persisted in long-term storage and record the history of messages and state for a @@ -29,12 +29,12 @@ to deliver that event to its recipient servers. However PDUs are signed using the originating server's private key so that it is possible to deliver them through third-party servers. -Ephemeral Data Units (EDUs): +Ephemeral Data Units (EDUs): These events are pushed between pairs of homeservers. They are not persisted and are not part of the history of a room, nor does the receiving homeserver have to reply to them. -Queries: +Queries: These are single request/response interactions between a given pair of servers, initiated by one side sending an HTTPS GET request to obtain some information, and responded by the other. They are not persisted and @@ -365,19 +365,19 @@ them. #### Definitions -Required Power Level +Required Power Level A given event type has an associated *required power level*. This is given by the current `m.room.power_levels` event. The event type is either listed explicitly in the `events` section or given by either `state_default` or `events_default` depending on if the event is a state event or not. -Invite Level, Kick Level, Ban Level, Redact Level +Invite Level, Kick Level, Ban Level, Redact Level The levels given by the `invite`, `kick`, `ban`, and `redact` properties in the current `m.room.power_levels` state. Each defaults to 50 if unspecified. -Target User +Target User For an `m.room.member` state event, the user given by the `state_key` of the event. @@ -720,6 +720,24 @@ other servers participating in the room. {{% http-api spec="server-server" api="joins-v2" %}} +## Knocking upon a room + +Rooms can permit knocking through the join rules, and if permitted this +gives users a way to request to join (be invited) to the room. Users who +knock on a room where the server is already a resident of the room can +just send the knock event directly without using this process, however +much like [joining rooms](/server-server-api/#joining-rooms) the server +must handshake their way into having the knock sent on its behalf. + +The handshake is largely the same as the joining rooms handshake, where +instead of a "joining server" there is a "knocking server", and the APIs +to be called are different (`/make_knock` and `/send_knock`). + +Servers can retract knocks over federation by leaving the room, as described +below for rejecting invites. + +{{% http-api spec="server-server" api="knocks" %}} + ## Inviting to a room When a user on a given homeserver invites another user on the same @@ -728,6 +746,10 @@ the process defined here. However, when a user invites another user on a different homeserver, a request to that homeserver to have the event signed and verified must be made. +Note that invites are used to indicate that knocks were accepted. As such, +receiving servers should be prepared to manually link up a previous knock +to an invite if the invite event does not directly reference the knock. + {{% http-api spec="server-server" api="invites-v1" %}} {{% http-api spec="server-server" api="invites-v2" %}} @@ -735,10 +757,10 @@ signed and verified must be made. ## Leaving Rooms (Rejecting Invites) Normally homeservers can send appropriate `m.room.member` events to have -users leave the room, or to reject local invites. Remote invites from -other homeservers do not involve the server in the graph and therefore -need another approach to reject the invite. Joining the room and -promptly leaving is not recommended as clients and servers will +users leave the room, to reject local invites, or to retract a knock. +Remote invites/knocks from other homeservers do not involve the server in the +graph and therefore need another approach to reject the invite. Joining +the room and promptly leaving is not recommended as clients and servers will interpret that as accepting the invite, then leaving the room rather than rejecting the invite. @@ -1009,6 +1031,8 @@ The following endpoint prefixes MUST be protected: - `/_matrix/federation/v2/send_leave` - `/_matrix/federation/v1/invite` - `/_matrix/federation/v2/invite` +- `/_matrix/federation/v1/make_knock` +- `/_matrix/federation/v1/send_knock` - `/_matrix/federation/v1/state` - `/_matrix/federation/v1/state_ids` - `/_matrix/federation/v1/backfill` diff --git a/data/api/client-server/definitions/public_rooms_response.yaml b/data/api/client-server/definitions/public_rooms_response.yaml index 04680246..8cf9935c 100644 --- a/data/api/client-server/definitions/public_rooms_response.yaml +++ b/data/api/client-server/definitions/public_rooms_response.yaml @@ -1,4 +1,4 @@ -# Copyright 2018 New Vector Ltd +# Copyright 2018, 2021 The Matrix.org Foundation C.I.C. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -69,6 +69,13 @@ properties: avatar_url: type: string description: The URL for the room's avatar, if one is set. + join_rule: + type: string + description: |- + The room's join rule. When not present, the room is assumed to + be `public`. Note that rooms with `invite` join rules are not + expected here, but rooms with `knock` rules are given their + near-public nature. next_batch: type: string description: |- @@ -96,7 +103,8 @@ example: { "num_joined_members": 37, "room_id": "!ol19s:bleecker.street", "topic": "Tasty tasty cheese", - "world_readable": true + "world_readable": true, + "join_rule": "public" } ], "next_batch": "p190q", diff --git a/data/api/client-server/knocking.yaml b/data/api/client-server/knocking.yaml new file mode 100644 index 00000000..0db92d5e --- /dev/null +++ b/data/api/client-server/knocking.yaml @@ -0,0 +1,124 @@ +# Copyright 2021 The Matrix.org Foundation C.I.C. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +swagger: '2.0' +info: + title: "Matrix Client-Server Room Knocking API" + version: "1.0.0" +host: localhost:8008 +schemes: + - https + - http +basePath: /_matrix/client/%CLIENT_MAJOR_VERSION% +consumes: + - application/json +produces: + - application/json +securityDefinitions: + $ref: definitions/security.yaml +paths: + "/knock/{roomIdOrAlias}": + post: + summary: Knock on a room, requesting permission to join. + description: |- + *Note that this API takes either a room ID or alias, unlike other membership APIs.* + + This API "knocks" on the room to ask for permission to join, if the user + is allowed to knock on the room. Acceptance of the knock happens out of + band from this API, meaning that the client will have to watch for updates + regarding the acceptance/rejection of the knock. + + If the room history settings allow, the user will still be able to see + history of the room while being in the "knock" state. The user will have + to accept the invitation to join the room (acceptance of knock) to see + messages reliably. See the `/join` endpoints for more information about + history visibility to the user. + + The knock will appear as an entry in the response of the + [`/sync`](/client-server-api/#get_matrixclientr0sync) API. + operationId: knockRoom + security: + - accessToken: [] + parameters: + - in: path + type: string + name: roomIdOrAlias + description: The room identifier or alias to knock upon. + required: true + x-example: "#monkeys:matrix.org" + - in: query + type: array + items: + type: string + name: server_name + description: |- + The servers to attempt to knock on the room through. One of the servers + must be participating in the room. + x-example: ["matrix.org", "elsewhere.ca"] + - in: body + name: body + required: true + schema: + type: object + properties: + reason: + type: string + description: |- + Optional reason to be included as the `reason` on the subsequent + membership event. + example: "Looking for support" + responses: + 200: + description: |- + The room has been knocked upon. + + The knocked room ID must be returned in the `room_id` field. + examples: + application/json: { + "room_id": "!d41d8cd:matrix.org" + } + schema: + type: object + properties: + room_id: + type: string + description: The knocked room ID. + required: ["room_id"] + 403: + description: |- + You do not have permission to knock on the room. A meaningful `errcode` + and description error text will be returned. Example reasons for rejection are: + + - The room is not set up for knocking. + - The user has been banned from the room. + examples: + application/json: { + "errcode": "M_FORBIDDEN", "error": "You are not allowed to knock on this room." + } + schema: + "$ref": "definitions/errors/error.yaml" + 404: + description: |- + The room could not be found or resolved to a room ID. + examples: + application/json: { + "errcode": "M_NOT_FOUND", "error": "That room does not appear to exist." + } + schema: + "$ref": "definitions/errors/error.yaml" + 429: + description: This request was rate-limited. + schema: + "$ref": "definitions/errors/rate_limited.yaml" + tags: + - Room membership diff --git a/data/api/client-server/sync.yaml b/data/api/client-server/sync.yaml index a7090d6b..140843a0 100644 --- a/data/api/client-server/sync.yaml +++ b/data/api/client-server/sync.yaml @@ -1,4 +1,4 @@ -# Copyright 2016 OpenMarket Ltd +# Copyright 2016, 2021 The Matrix.org Foundation C.I.C. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -281,6 +281,28 @@ paths: items: $ref: "../../event-schemas/schema/stripped_state.yaml" type: array + knock: + title: Knocked rooms + type: object + description: |- + The rooms that the user has knocked upon, mapped as room ID to room information. + additionalProperties: + title: Knocked Room + type: object + properties: + knock_state: + title: KnockState + type: object + description: |- + The state of a room that the user has knocked upon. The state + events contained here have the same restrictions as `InviteState` + above. + properties: + events: + description: The StrippedState events that form the knock state. + items: + $ref: "../../event-schemas/schema/stripped_state.yaml" + type: array leave: title: Left rooms type: object @@ -436,6 +458,26 @@ paths: } } }, + "knock": { + "!223asd456:example.com": { + "invite_state": { + "events": [ + { + "sender": "@alice:example.com", + "type": "m.room.name", + "state_key": "", + "content": {"name": "My Room Name"} + }, + { + "sender": "@bob:example.com", + "type": "m.room.member", + "state_key": "@bob:example.com", + "content": {"membership": "knock"} + } + ] + } + } + }, "leave": {} } } diff --git a/data/api/server-server/knocks.yaml b/data/api/server-server/knocks.yaml new file mode 100644 index 00000000..b774d088 --- /dev/null +++ b/data/api/server-server/knocks.yaml @@ -0,0 +1,321 @@ +# Copyright 2021 The Matrix.org Foundation C.I.C. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +swagger: '2.0' +info: + title: "Matrix Federation Knock Room API" + version: "1.0.0" +host: localhost:8448 +schemes: + - https +basePath: /_matrix/federation/v1 +consumes: + - application/json +produces: + - application/json +securityDefinitions: + $ref: definitions/security.yaml +paths: + "/make_knock/{roomId}/{userId}": + get: + summary: Get information required to make a knock event for a room. + description: |- + Asks the receiving server to return information that the sending + server will need to prepare a knock event for the room. + operationId: makeKnock + security: + - signedRequest: [] + parameters: + - in: path + name: roomId + type: string + description: The room ID that is about to be knocked. + required: true + x-example: "!abc123:example.org" + - in: path + name: userId + type: string + description: The user ID the knock event will be for. + required: true + x-example: "@someone:example.org" + - in: query + type: array + items: + type: string + name: ver + description: |- + The room versions the sending server has support for. + required: true # knocking was supported in v7 + x-example: ["1", "7"] + responses: + 200: + description: |- + A template to be used for the rest of the [KNocking Rooms](/server-server-api/#knocking-rooms) + handshake. Note that events have a different format depending on room version - check the + [room version specification](/#room-versions) for precise event formats. **The response body + here describes the common event fields in more detail and may be missing other + required fields for a PDU.** + schema: + type: object + properties: + room_version: + type: string + required: true # knocking was supported in v7 + description: |- + The version of the room where the server is trying to knock. + example: "7" + event: + description: |- + An unsigned template event. Note that events have a different format + depending on the room version - check the [room version specification](/#room-versions) + for precise event formats. + type: object + title: Event Template + properties: + sender: + type: string + description: The user ID of the knocking member. + example: "@someone:example.org" + origin: + type: string + description: The name of the resident homeserver. + example: "matrix.org" + origin_server_ts: + type: integer + format: int64 + description: A timestamp added by the resident homeserver. + example: 1234567890 + type: + type: string + description: The value `m.room.member`. + example: "m.room.member" + state_key: + type: string + description: The user ID of the knocking member. + example: "@someone:example.org" + content: + type: object + title: Membership Event Content + description: The content of the event. + example: {"membership": "knock"} + properties: + membership: + type: string + description: The value `knock`. + example: "knock" + required: ['membership'] + required: + - state_key + - origin + - origin_server_ts + - type + - content + - sender + examples: + application/json: { + "room_version": "7", + "event": { + "$ref": "examples/minimal_pdu.json", + "type": "m.room.member", + "state_key": "@someone:example.org", + "origin": "example.org", + "origin_server_ts": 1549041175876, + "sender": "@someone:example.org", + "content": { + "membership": "knock" + } + } + } + 400: + description: |- + The request is invalid or the room the server is attempting + to knock upon has a version that is not listed in the `ver` + parameters. + + The error should be passed through to clients so that they + may give better feedback to users. + schema: + allOf: + - $ref: "../client-server/definitions/errors/error.yaml" + - type: object + properties: + room_version: + type: string + description: |- + The version of the room. Required if the `errcode` + is `M_INCOMPATIBLE_ROOM_VERSION`. + examples: + application/json: { + "errcode": "M_INCOMPATIBLE_ROOM_VERSION", + "error": "Your homeserver does not support the features required to knock on this room", + "room_version": "7" + } + 404: + description: |- + The room that the knocking server is attempting to knock upon is unknown + to the receiving server. + schema: + allOf: + - $ref: "../client-server/definitions/errors/error.yaml" + examples: + application/json: { + "errcode": "M_NOT_FOUND", + "error": "Unknown room", + } + 403: + description: |- + The knocking server or user is not permitted to knock on the room, such as when the + server/user is banned or the room is not set up for receiving knocks. + schema: + allOf: + - $ref: "../client-server/definitions/errors/error.yaml" + examples: + application/json: { + "errcode": "M_FORBIDDEN", + "error": "You are not permitted to knock on this room", + } + + "/send_knock/{roomId}/{eventId}": + put: + summary: Submit a signed knock event to a resident server. + description: |- + Submits a signed knock event to the resident server for it to + accept into the room's graph. Note that events have + a different format depending on the room version - check + the [room version specification](/#room-versions) for precise event formats. + **The request and response body here describe the common + event fields in more detail and may be missing other required + fields for a PDU.** + operationId: sendKnock + security: + - signedRequest: [] + parameters: + - in: path + name: roomId + type: string + description: The room ID that is about to be knocked upon. + required: true + x-example: "!abc123:example.org" + - in: path + name: eventId + type: string + description: The event ID for the knock event. + required: true + x-example: "$abc123:example.org" + - in: body + name: body + type: object + required: true + schema: + type: object + properties: + sender: + type: string + description: The user ID of the knocking member. + example: "@someone:example.org" + origin: + type: string + description: The name of the knocking homeserver. + example: "matrix.org" + origin_server_ts: + type: integer + format: int64 + description: A timestamp added by the knocking homeserver. + example: 1234567890 + type: + type: string + description: The value `m.room.member`. + example: "m.room.member" + state_key: + type: string + description: The user ID of the knocking member. + example: "@someone:example.org" + content: + type: object + title: Membership Event Content + description: The content of the event. + example: {"membership": "knock"} + properties: + membership: + type: string + description: The value `knock`. + example: "knock" + required: ['membership'] + required: + - state_key + - sender + - origin + - origin_server_ts + - type + - content + example: { + "$ref": "examples/minimal_pdu.json", + "type": "m.room.member", + "state_key": "@someone:example.org", + "origin": "example.org", + "origin_server_ts": 1549041175876, + "sender": "@someone:example.org", + "content": { + "membership": "knock" + } + } + responses: + 200: + description: |- + Information about the room to pass along to clients regarding the + knock. + schema: + type: object + properties: + knock_room_state: + type: array + items: + $ref: "../../event-schemas/schema/stripped_state.yaml" + description: |- + A list of simplified events to help the initiator of the knock identify + the room. The recommended events to include are the join rules, canonical + alias, avatar, name, and encryption state of the room. + example: + $ref: "../../event-schemas/examples/knock_room_state.json" + required: ['knock_room_state'] + examples: + application/json: { + "knock_room_state": {"$ref": "../../event-schemas/examples/knock_room_state.json"} + } + 404: + description: |- + The room that the knocking server is attempting to knock upon is unknown + to the receiving server. + schema: + allOf: + - $ref: "../client-server/definitions/errors/error.yaml" + examples: + application/json: { + "errcode": "M_NOT_FOUND", + "error": "Unknown room", + } + 403: + description: |- + The knocking server or user is not permitted to knock on the room, such as when the + server/user is banned or the room is not set up for receiving knocks. + schema: + allOf: + - $ref: "../client-server/definitions/errors/error.yaml" + examples: + application/json: { + "errcode": "M_FORBIDDEN", + "error": "You are not permitted to knock on this room", + } + + diff --git a/data/api/server-server/public_rooms.yaml b/data/api/server-server/public_rooms.yaml index e52f6d48..23517785 100644 --- a/data/api/server-server/public_rooms.yaml +++ b/data/api/server-server/public_rooms.yaml @@ -1,4 +1,4 @@ -# Copyright 2018 New Vector Ltd +# Copyright 2018, 2021 The Matrix.org Foundation C.I.C. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -193,6 +193,13 @@ paths: avatar_url: type: string description: The URL for the room's avatar, if one is set. + join_rule: + type: string + description: |- + The room's join rule. When not present, the room is assumed to + be `public`. Note that rooms with `invite` join rules are not + expected here, but rooms with `knock` rules are given their + near-public nature. next_batch: type: string description: |- @@ -221,7 +228,8 @@ paths: "num_joined_members": 37, "room_id": "!ol19s:bleecker.street", "topic": "Tasty tasty cheese", - "world_readable": true + "world_readable": true, + "join_rule": "public" } ], "next_batch": "p190q", diff --git a/data/event-schemas/examples/knock_room_state.json b/data/event-schemas/examples/knock_room_state.json new file mode 100644 index 00000000..9692bb31 --- /dev/null +++ b/data/event-schemas/examples/knock_room_state.json @@ -0,0 +1,18 @@ +[ + { + "type": "m.room.name", + "sender": "@bob:example.org", + "state_key": "", + "content": { + "name": "Example Room" + } + }, + { + "type": "m.room.join_rules", + "sender": "@bob:example.org", + "state_key": "", + "content": { + "join_rule": "knock" + } + } +] diff --git a/data/event-schemas/examples/m.room.member$knock_room_state.yaml b/data/event-schemas/examples/m.room.member$knock_room_state.yaml new file mode 100644 index 00000000..c1ec3a32 --- /dev/null +++ b/data/event-schemas/examples/m.room.member$knock_room_state.yaml @@ -0,0 +1,15 @@ +{ + "$ref": "m.room.member.yaml", + "content": { + "membership": "knock", + "avatar_url": "mxc://example.org/SEsfnsuifSDFSSEF", + "displayname": "Alice Margatroid", + "reason": "Looking for support" + }, + "unsigned": { + "age": 1234, + "knock_room_state": { + "$ref": "knock_room_state.json" + } + } +} diff --git a/data/event-schemas/schema/m.room.join_rules.yaml b/data/event-schemas/schema/m.room.join_rules.yaml index faa0f249..5f0e11af 100644 --- a/data/event-schemas/schema/m.room.join_rules.yaml +++ b/data/event-schemas/schema/m.room.join_rules.yaml @@ -1,7 +1,16 @@ --- allOf: - $ref: core-event-schema/state_event.yaml -description: 'A room may be `public` meaning anyone can join the room without any prior action. Alternatively, it can be `invite` meaning that a user who wishes to join the room must first receive an invite to the room from someone already inside of the room. Currently, `knock` and `private` are reserved keywords which are not implemented.' +description: | + A room may be `public` meaning anyone can join the room without any prior action. + Alternatively, it can be `invite` meaning that a user who wishes to join the room + must first receive an invite to the room from someone already inside of the room. + `knock` means that users are able to ask for permission to join the room, where + they are either allowed (invited) or denied (kicked/banned) access. Join rules + of `knock` are otherwise the same as `invite`: the user needs an explicit invite + to join the room. + + Currently, `private` is a reserved keyword which is not implemented. properties: content: properties: diff --git a/data/event-schemas/schema/m.room.member.yaml b/data/event-schemas/schema/m.room.member.yaml index 181c5737..928e1528 100644 --- a/data/event-schemas/schema/m.room.member.yaml +++ b/data/event-schemas/schema/m.room.member.yaml @@ -14,7 +14,7 @@ description: |- - `ban` - The user has been banned from the room, and is no longer allowed to join it until they are un-banned from the room (by having their membership state set to a value other than `ban`). - - `knock` - This is a reserved word, which currently has no meaning. + - `knock` - The user has knocked on the room, requesting permission to participate. They may not participate in the room until they join. The `third_party_invite` property will be set if this invite is an `invite` event and is the successor of an `m.room.third_party_invite` event, and absent otherwise. @@ -31,13 +31,13 @@ description: |- from the `prev_content` object on an event. If not present, the user's previous membership must be assumed as `leave`. - | | to `invite` | to `join` | to `leave` | to `ban` | to `knock` | - |-------------------|---------------------|----------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------|-----------------------------|------------------| - | **from `invite`** | No change. | User joined the room. | If the `state_key` is the same as the `sender`, the user rejected the invite. Otherwise, the `state_key` user had their invite revoked. | User was banned. | Not implemented. | - | **from `join`** |Must never happen. | `displayname` or `avatar_url` changed. | If the `state_key` is the same as the `sender`, the user left. Otherwise, the `state_key` user was kicked. | User was kicked and banned. | Not implemented. | - | **from `leave`** |New invitation sent. | User joined. | No change. | User was banned. | Not implemented. | - | **from `ban`** |Must never happen. | Must never happen. | User was unbanned. | No change. | Not implemented. | - | **from `knock`** |Not implemented. | Not implemented. | Not implemented. | Not implemented. | Not implemented. | + | | to `invite` | to `join` | to `leave` | to `ban` | to `knock` | + |-------------------|----------------------|----------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------|-----------------------------|--------------------| + | **from `invite`** | No change. | User joined the room. | If the `state_key` is the same as the `sender`, the user rejected the invite. Otherwise, the `state_key` user had their invite revoked. | User was banned. | Must never happen. | + | **from `join`** | Must never happen. | `displayname` or `avatar_url` changed. | If the `state_key` is the same as the `sender`, the user left. Otherwise, the `state_key` user was kicked. | User was kicked and banned. | Must never happen. | + | **from `leave`** | New invitation sent. | User joined. | No change. | User was banned. | User is knocking. | + | **from `ban`** | Must never happen. | Must never happen. | User was unbanned. | No change. | Must never happen. | + | **from `knock`** | Knock accepted. | Must never happen. | If the `state_key` is the same as the `sender`, the user retracted the knock. Otherwise, the `state_key` user had their knock denied. | User was banned. | No change. | properties: content: @@ -124,7 +124,24 @@ properties: - type: object properties: invite_room_state: - description: 'A subset of the state of the room at the time of the invite, if `membership` is `invite`. Note that this state is informational, and SHOULD NOT be trusted; once the client has joined the room, it SHOULD fetch the live state from the server and discard the invite_room_state. Also, clients must not rely on any particular state being present here; they SHOULD behave properly (with possibly a degraded but not a broken experience) in the absence of any particular events here. If they are set on the room, at least the state for `m.room.avatar`, `m.room.canonical_alias`, `m.room.join_rules`, and `m.room.name` SHOULD be included.' + description: |- + A subset of the state of the room at the time of the invite, if `membership` is `invite`. + Note that this state is informational, and SHOULD NOT be trusted; once the client has + joined the room, it SHOULD fetch the live state from the server and discard the + invite_room_state. Also, clients must not rely on any particular state being present here; + they SHOULD behave properly (with possibly a degraded but not a broken experience) in + the absence of any particular events here. If they are set on the room, at least the + state for `m.room.avatar`, `m.room.canonical_alias`, `m.room.join_rules`, and `m.room.name` + SHOULD be included. + items: + $ref: "stripped_state.yaml" + type: array + knock_room_state: + description: |- + A subset of the state of the room at the time of the knock, if `membership` is `knock`. + This has the same restrictions as `invite_room_state`. If they are set on the room, at least + the state for `m.room.avatar`, `m.room.canonical_alias`, `m.room.join_rules`, `m.room.name`, + and `m.room.encryption` SHOULD be included. items: $ref: "stripped_state.yaml" type: array diff --git a/static/diagrams/README.md b/static/diagrams/README.md new file mode 100644 index 00000000..0b74734c --- /dev/null +++ b/static/diagrams/README.md @@ -0,0 +1,17 @@ +# Spec diagrams + +Non-ascii diagrams for the spec can be placed here for reference in the actual spec. +Please include source material so the diagram can be recreated by a future editor. + +https://www.diagrams.net/ is a great ([open source](https://github.com/jgraph/drawio)) +tool for these sorts of things - include your `.drawio` file next to your diagram. + +Suggested settings for diagrams.net: +* Export as PNG. +* 100% size. +* `20` for a border width. +* No transparent background, shadow, or grid. +* Include a copy of the diagram. + +To reference a diagram, use the absolute path when compiled. For example, +`![membership-flow-diagram](/diagrams/membership.png)` diff --git a/static/diagrams/membership.drawio b/static/diagrams/membership.drawio new file mode 100644 index 00000000..1c6708de --- /dev/null +++ b/static/diagrams/membership.drawio @@ -0,0 +1 @@ +3Vvdb6M4EP9rIt09NMIGA3ncZtvbh73TSn243X1ZOYmT0BIcOaZJ9q8/E0z4cggEgulVqoqHsbHHv/nwjDsyp5vDXwxv13/TBfFH0FgcRubnEYTAAa74E1GOMWViopiwYt5CMqWEF+83kURDUkNvQXY5Rk6pz71tnjinQUDmPEfDjNF9nm1J/fxXt3hFSoSXOfbL1H+9BV/HVBc6Kf0L8Vbr5MvAnsRvNjhhlivZrfGC7jMk82lkThmlPH7aHKbEj4SXyCXu93zh7XlijAS8TodvBvr96euj/xL83G+Dn2gaTvgDkMO8Yz+UKxYjvFIvkJPmx0QSZCEEI5uU8TVd0QD7Tyn1kdEwWJDoc4ZopTxfKd0KIhDEV8L5Ue4yDjkVpDXf+PJt/M3oQxfXKEk7GrI5qVqYxApmK8Ir+OB5JwSECd0Qzo6iHyM+5t57fh5YYml15pNdPzGGjxmGrZAf32VG/hYRBINUCziRmJBKYdqFrWvGLx7iGSStzFJS0gkOTaBhqaDhEyykogEb5ODx75nnH9FQY4hk8/NBDn1qHJNGIGTwPcMZtX9kX6b9Tq2kY4dIhKgmFC01FCUGjDEwHDMeqhk6S3Cy3DycoDUZ25kfx8qPGM9cDpLCrinqLVD4rG1Wot4CqIo/j/q0dzIdulzuCC/06EYzSorhBe8eL6tFHvT7teB52eITWvbCXaqM3zthnByqQXcRI9ApSBjJ9j51XcCQtHXGbSV8KgzlpNdYVHaFETEoG0VO6/nNm799cH8DO1JysRduOyW/P/4hVG3qDGuJGRK/YIxRxjOA29wC6NEt1ASMWQmYB2NsI6ulW+gBMSXAKEPMRvZySQP+jDeeH23OVIjbI5E5+Yfs72NMLUu7MXVVehcGujUvF5HVDMhAVu1kr34Uz2xnqWsrWautNks7rdrkQekLQoVDiqldX5R+KrY8hreMVhfOfG8+grYv5vI4E/KwV9FTxPOLhT7Z6XVp8Caf5ug66lg1VavtobsdKsq6Jca5EMH3sduXNq7HYKT2xqFr0QgaeigCnEEGr05W0426mq4tqVEXMBei1340vZzAUmevBuVGzWKuT7sbVUadGu1lO53RFnfCSWdG1rVdq52dPddnCgkjB+WHiFdVSv31arCNjx3F5RPW1ccjLXBraaLrIcuy6yGrs4yDsrCly82nHrtRhHdLbksHhK7mqFxogrsYLGTVg1XTWgUo1CqQWV2hs41Kfn21CqhMwA/Ae9+SNGp6tM3Fal+I/064N8cdK0lHZycRzN+iIU2BbVr5ohqYoIEAVXkuG0qlqGWV4eOitrpeJUy7A4ZffjAHFQzcEBf+L6B0NUpwEGoZJfRgpspJhbeAKozSoJMK5zBKW1IhuRXT8SWKvouC+m9YJEF6RpBPB06YMEknl1k8FP8R0JOmiN8N2cwI+7NC4qChxMsmpl1JqXCGVKXCoELY9r2EbSpzEdIAxMmIU+MBz4QwB5qQKJSVaiebu/E8r+Fmmyw0oAFJSPGsHV1JkKtxjuvCm3JuTQP0wt08YFUfPM+3EtT8Gi/Jle2S/pjrVug3O3ZmIY7ZvGNI171OejXcmvRy4ISTwoETXcmkwEr+ewBaNNNr+DF7+s8M5tN/ \ No newline at end of file diff --git a/static/diagrams/membership.png b/static/diagrams/membership.png new file mode 100644 index 0000000000000000000000000000000000000000..891b338b92a2307a0049aeb04e30781a8ded4386 GIT binary patch literal 28770 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 arL~JkS+X^yPJrHlByfeh@&&Sne*XdiKIv-! literal 0 HcmV?d00001 From 2d39ed69c3736e93e5d4c348ff9faff676eeed50 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 28 Apr 2021 19:53:02 -0600 Subject: [PATCH 59/63] Add changelogs --- changelogs/client_server/newsfragments/3154.feature | 1 + changelogs/server_server/newsfragments/3154.feature | 1 + changelogs/server_server/newsfragments/3154.new | 1 + 3 files changed, 3 insertions(+) create mode 100644 changelogs/client_server/newsfragments/3154.feature create mode 100644 changelogs/server_server/newsfragments/3154.feature create mode 100644 changelogs/server_server/newsfragments/3154.new diff --git a/changelogs/client_server/newsfragments/3154.feature b/changelogs/client_server/newsfragments/3154.feature new file mode 100644 index 00000000..c73c27ec --- /dev/null +++ b/changelogs/client_server/newsfragments/3154.feature @@ -0,0 +1 @@ +Add support for knocking, as per [MSC2403](https://github.com/matrix-org/matrix-doc/pull/2403). \ No newline at end of file diff --git a/changelogs/server_server/newsfragments/3154.feature b/changelogs/server_server/newsfragments/3154.feature new file mode 100644 index 00000000..c73c27ec --- /dev/null +++ b/changelogs/server_server/newsfragments/3154.feature @@ -0,0 +1 @@ +Add support for knocking, as per [MSC2403](https://github.com/matrix-org/matrix-doc/pull/2403). \ No newline at end of file diff --git a/changelogs/server_server/newsfragments/3154.new b/changelogs/server_server/newsfragments/3154.new new file mode 100644 index 00000000..7791516f --- /dev/null +++ b/changelogs/server_server/newsfragments/3154.new @@ -0,0 +1 @@ +Add `/make_knock` and `/send_knock` endpoints as per [MSC2403](https://github.com/matrix-org/matrix-doc/pull/2403). \ No newline at end of file From ee3ca86b6c6b45f660ce23552fa29e7fbd805aba Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 28 Apr 2021 19:54:58 -0600 Subject: [PATCH 60/63] Declare required properties correctly --- data/api/server-server/knocks.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/data/api/server-server/knocks.yaml b/data/api/server-server/knocks.yaml index b774d088..9544c355 100644 --- a/data/api/server-server/knocks.yaml +++ b/data/api/server-server/knocks.yaml @@ -71,7 +71,6 @@ paths: properties: room_version: type: string - required: true # knocking was supported in v7 description: |- The version of the room where the server is trying to knock. example: "7" @@ -122,6 +121,9 @@ paths: - type - content - sender + required: + - room_version # knocking was added in v7 + - event examples: application/json: { "room_version": "7", From 8bbcee39a55151e224a86be69bd0c5d0550a9850 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 29 Apr 2021 16:39:02 -0600 Subject: [PATCH 61/63] Update data/api/server-server/knocks.yaml Co-authored-by: Hubert Chathi --- data/api/server-server/knocks.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/data/api/server-server/knocks.yaml b/data/api/server-server/knocks.yaml index 9544c355..945362a1 100644 --- a/data/api/server-server/knocks.yaml +++ b/data/api/server-server/knocks.yaml @@ -61,7 +61,7 @@ paths: responses: 200: description: |- - A template to be used for the rest of the [KNocking Rooms](/server-server-api/#knocking-rooms) + A template to be used for the rest of the [Knocking Rooms](/server-server-api/#knocking-rooms) handshake. Note that events have a different format depending on room version - check the [room version specification](/#room-versions) for precise event formats. **The response body here describes the common event fields in more detail and may be missing other @@ -320,4 +320,3 @@ paths: "error": "You are not permitted to knock on this room", } - From 57f4347b5d1447044b0dc39f4baba5f252074608 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 29 Apr 2021 22:19:27 -0600 Subject: [PATCH 62/63] Fix general wording --- content/client-server-api/_index.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/content/client-server-api/_index.md b/content/client-server-api/_index.md index a9103c7a..ec26cec8 100644 --- a/content/client-server-api/_index.md +++ b/content/client-server-api/_index.md @@ -1785,11 +1785,17 @@ relation to a room: - Joined (the user can send and receive events in the room) - Banned (the user is not allowed to join the room) -There is an exception to the requirement that a user join a room before -sending events to it: users may send an `m.room.member` event to a room -with `content.membership` set to `leave` to reject an invitation if they -have currently been invited to a room but have not joined it. The same -applies for retracting knocks on the room that the user sent. +There are a few notable exceptions which allow non-joined members of the +room to send events in the room: + +- Users wishing to reject an invite would send `m.room.member` events with + `content.membership` of `leave`. They must have been invited first. + +- If the room allows, users can send `m.room.member` events with `content.membership` + of `knock` to knock on the room. This is a request for an invite by the user. + +- To retract a previous knock, a user would send a `leave` event similar to + rejecting an invite. Some rooms require that users be invited to it before they can join; others allow anyone to join. Whether a given room is an "invite-only" From 01a7f06ce45821dff270c54a71463bb20cbb3aa4 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 29 Apr 2021 22:19:54 -0600 Subject: [PATCH 63/63] Add missing endpoint changelog --- changelogs/client_server/newsfragments/3154.new | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/3154.new diff --git a/changelogs/client_server/newsfragments/3154.new b/changelogs/client_server/newsfragments/3154.new new file mode 100644 index 00000000..aa89f639 --- /dev/null +++ b/changelogs/client_server/newsfragments/3154.new @@ -0,0 +1 @@ +Add `/knock` endpoint as per [MSC2403](https://github.com/matrix-org/matrix-doc/pull/2403). \ No newline at end of file