diff --git a/docs/protocol/diagrams/group.mmd b/docs/protocol/diagrams/group.mmd
index 18d392caa5..6a9bd0c786 100644
--- a/docs/protocol/diagrams/group.mmd
+++ b/docs/protocol/diagrams/group.mmd
@@ -4,9 +4,16 @@ sequenceDiagram
participant B as Bob
participant C as Existing
contact
- note over A, B: 1. send and accept group invitation
- A ->> B: x.grp.inv
invite Bob to group
(via contact connection)
- B ->> A: x.grp.acpt
accept invitation
(via member connection)
establish group member connection
+ alt invite contact
+ note over A, B: 1a. send and accept group invitation
+ A ->> B: x.grp.inv
invite Bob to group
(via contact connection)
+ B ->> A: x.grp.acpt
accept invitation
(via member connection)
establish group member connection
+ else join via group link
+ note over A, B: 1b. join via group link and accept request
+ B ->> A: join via group link
SimpleX contact address
+ A ->> B: x.grp.link.inv in SMP confirmation
accept joining member request,
sending group profile, etc.
establish group member connection
+ A ->> B: x.grp.link.mem
send inviting member profile
+ end
note over M, B: 2. introduce new member Bob to all existing members
A ->> M: x.grp.mem.new
"announce" Bob
to existing members
(via member connections)
@@ -20,14 +27,25 @@ sequenceDiagram
end
A ->> M: x.grp.mem.fwd
forward "invitations" and
Bob's chat protocol version
to all members
(via member connections)
+ note over M, B: group message forwarding
(while connections between members are being established)
+ M -->> B: messages between members and Bob are forwarded by Alice
+ B -->> M:
+
note over M, B: 3. establish direct and group member connections
M ->> B: establish group member connection
opt chat protocol compatible version < 2
M ->> B: establish direct connection
- note over M, C: 4. deduplicate new contact
+ note over M, C: 3*. deduplicate new contact
B ->> M: x.info.probe
"probe" is sent to all new members
B ->> C: x.info.probe.check
"probe" hash,
in case contact and
member profiles match
C ->> B: x.info.probe.ok
original "probe",
in case contact and member
are the same user
note over B: merge existing and new contacts if received and sent probe hashes match
end
+
+ note over M, B: 4. notify inviting member that connection is established
+ M ->> A: x.grp.mem.con
+ B ->> A: x.grp.mem.con
+ note over A: stops forwarding messages
+ M -->> B: messages are sent via group connection without forwarding
+ B -->> M:
diff --git a/docs/protocol/diagrams/group.svg b/docs/protocol/diagrams/group.svg
index 8c1b65dee2..f3c9aa8a26 100644
--- a/docs/protocol/diagrams/group.svg
+++ b/docs/protocol/diagrams/group.svg
@@ -1 +1,3 @@
-
\ No newline at end of file
+
+
+
\ No newline at end of file
diff --git a/docs/protocol/simplex-chat.html b/docs/protocol/simplex-chat.html
index 9b409480a4..296914eed7 100644
--- a/docs/protocol/simplex-chat.html
+++ b/docs/protocol/simplex-chat.html
@@ -735,7 +735,7 @@ window.addEventListener('scroll',changeHeaderBg);
-
DRAFT Revision 0.1, 2022-08-08
+Revision 2, 2024-06-24
Evgeny Poberezkin
This message is sent by both sides of the connection during the connection handshake, and can be sent later as well when contact profile is updated.
As there are no globally unique user identitifiers, when the contact a user is already connected to is added to the group by some other group member, this contact will be added to user's list of contacts as a new contact. To allow merging such contacts, "a probe" (random base64url-encoded 32 bytes) SHOULD be sent to all new members as part of x.info.probe message and, in case there is a contact with the same profile, the hash of the probe MAY be sent to it as part of x.info.probe.check message. In case both the new member and the existing contact are the same user (they would receive both the probe and its hash), the contact would send back the original probe as part of x.info.probe.ok message via the previously existing contact connection – proving to the sender that this new member and the existing contact are the same user, in which case the sender SHOULD merge these two contacts.
As there are no globally unique user identifiers, when the contact a user is already connected to is added to the group by some other group member, this contact will be added to user's list of contacts as a new contact. To allow merging such contacts, "a probe" (random base64url-encoded 32 bytes) SHOULD be sent to all new members as part of x.info.probe message and, in case there is a contact with the same profile, the hash of the probe MAY be sent to it as part of x.info.probe.check message. In case both the new member and the existing contact are the same user (they would receive both the probe and its hash), the contact would send back the original probe as part of x.info.probe.ok message via the previously existing contact connection – proving to the sender that this new member and the existing contact are the same user, in which case the sender SHOULD merge these two contacts.
Sending clients MAY disable this functionality, and receiving clients MAY ignore probe messages.
If the sending client uses x.info.probe messages, it MUST send them to all new members, rather than only when there is a matching contact profile. This is to avoid leaking information that the matching contact profile exists.
x.msg.file.descr message is used to send XFTP file description. File descriptions that don't fit into a single chat protocol message are sent in parts, with messages including part number (fileDescrPartNo) and description completion marker (fileDescrComplete). Recipient client accumulates description parts and starts file download upon completing file description.
SimpleX Chat groups are fully decentralized and do not have any globally unique group identifiers - they are only defined on client devices as a group profile and a set of bi-directional SimpleX connections with other group members. When a new member accepts group invitation, the inviting member introduces a new member to all existing members and forwards the connection addresses so that they can establish direct and group member connections.
+SimpleX Chat groups are fully decentralized and do not have any globally unique group identifiers - they are only defined on client devices as a group profile and a set of bi-directional SimpleX connections with other group members. When a new member accepts group invitation or joins via group link, the inviting member introduces a new member to all existing members and forwards the connection addresses so that they can establish direct and group member connections.
There is a possibility of the attack here: as the introducing member forwards the addresses, they can substitute them with other addresses, performing MITM attack on the communication between existing and introduced members - this is similar to the communication operator being able to perform MITM on any connection between the users. To mitigate this attack this group sub-protocol will be extended to allow validating security of the connection by sending connection verification out-of-band.
-Clients are RECOMMENDED to indicate in the UI whether the connection to a group member or contact was made directly or via annother user.
+Clients are RECOMMENDED to indicate in the UI whether the connection to a group member or contact was made directly or via another user.
Each member in the group is identified by a group-wide unique identifier used by all members in the group. This is to allow referencing members in the messages and to allow group message integrity validation.
The diagram below shows the sequence of messages sent between the users' clients to add the new member to the group.
-While introduced members establish connection inside group, inviting member forwards messages between them by sending x.grp.msg.forward messages. When introduced members finalize connection, they notify inviting member to stop forwarding via x.grp.mem.con message.
Currently members can have one of three roles - owner, admin and member. The user that created the group is self-assigned owner role, the new members are assigned role by the member who adds them - only owner and admin members can add new members; only owner members can add members with owner role.
Currently members can have one of three roles - owner, admin, member and observer. The user that created the group is self-assigned owner role, the new members are assigned role by the member who adds them - only owner and admin members can add new members; only owner members can add members with owner role. Observer members only receive messages and aren't allowed to send messages.
x.grp.inv message is sent to invite contact to the group via contact's direct connection and includes group member connection address. This message MUST only be sent by members with admin or owner role. Optional groupLinkId is included when this message is sent to contacts connected via the user's group link. This identifier is a random byte sequence, with no global or even local uniqueness - it is only used for the user's invitations to a given group to provide confirmation to the contact that the group invitation is for the same group the contact was connecting to via the group link, so that the invitation can be automatically accepted by the contact - the contact compares it with the group link id contained in the group link uri's data field.
x.grp.acpt message is sent as part of group member connection handshake, only to the inviting user.
x.call.end message is sent to notify the other party that the call is terminated.
This threat model compliments SMP, XFTP, push notifications and XRCP protocols threat models:
+can:
+send messages prohibited by user's preferences or otherwise act non-compliantly with user's preferences (for example, if message with updated preferences was lost or failed to be processed, or with modified client), in which case user client should treat such messages and actions as prohibited.
+by exchanging special messages with user's client, match user's contact with existing group members and/or contacts that have identical user profile (see Probing for duplicate contacts).
+identify that and when a user is using SimpleX, in case user has delivery receipts enabled, or based on other automated client responses.
+cannot:
+match user's contact with existing group members and/or contacts with different or with incognito profiles.
+match user's contact without communicating with the user's client.
+can:
+send messages prohibited by group's preferences and member restrictions or otherwise act non-compliantly with preferences and restrictions (for example, if decentralized group state diverged, or with modified client), in which case user client should treat such messages and actions as prohibited.
+create a direct contact with a user if group permissions allow it.
+by exchanging special messages with user's client, match user's group member record with the existing group members and/or contacts that have identical user profile.
+undetectably send different messages to different group members, or selectively send messages to some members and not send to others.
+identify that and when a user is using SimpleX, in case user has delivery receipts enabled, or based on other automated client responses.
+join the same group several times, from the same or from different user profile, and pretend to be different members.
+cannot:
+match user's contact with existing group members and/or contacts with different or with incognito profiles.
+match user's group member record with existing group members and/or contacts without communication of user's client.
+determine whether two group members with different or with incognito profiles are the same user.
+can:
+carry out MITM attack between user and other group member(s) when forwarding invitations for group connections (user can detect such attack by verifying connection security codes out-of-band).
+undetectably forward different messages to different group members, selectively adding, modifying, and dropping forwarded messages.
+disrupt decentralized group state by sending different messages that change group state (such as adding or removing members, member role changes, etc.) to different group members, or sending such messages selectively.
+cannot:
+