diff --git a/conduit-example.toml b/conduit-example.toml index e551e0227f91d9e9acba5478c0cb2b12a053fcf3..e8d4b08de17c5bf65269bdcb92109bc3e954130e 100644 --- a/conduit-example.toml +++ b/conduit-example.toml @@ -63,4 +63,8 @@ allow_public_room_directory_over_federation = false # Set this to true to allow your server's public room directory to be queried without client authentication (access token) through the Client APIs. # Set this to false to protect against /publicRooms spiders. -allow_public_room_directory_without_auth = false \ No newline at end of file +allow_public_room_directory_without_auth = false + +# Set this to true to allow federating device display names / allow external users to see your device display name. +# If federation is disabled entirely (`allow_federation`), this is inherently false. +allow_device_name_federation = false diff --git a/src/api/client_server/keys.rs b/src/api/client_server/keys.rs index 7dbe040db6f2526102ab70fe500f21b960f4af9b..bc0887e3cf3ef0068cdedf0f891626f8697dcc6b 100644 --- a/src/api/client_server/keys.rs +++ b/src/api/client_server/keys.rs @@ -72,8 +72,13 @@ pub async fn upload_keys_route( pub async fn get_keys_route(body: Ruma<get_keys::v3::Request>) -> Result<get_keys::v3::Response> { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); - let response = - get_keys_helper(Some(sender_user), &body.device_keys, |u| u == sender_user).await?; + let response = get_keys_helper( + Some(sender_user), + &body.device_keys, + |u| u == sender_user, + true, // Always allow local users to see device names of other local users + ) + .await?; Ok(response) } @@ -259,6 +264,7 @@ pub(crate) async fn get_keys_helper<F: Fn(&UserId) -> bool>( sender_user: Option<&UserId>, device_keys_input: &BTreeMap<OwnedUserId, Vec<OwnedDeviceId>>, allowed_signatures: F, + include_display_names: bool, ) -> Result<get_keys::v3::Response> { let mut master_keys = BTreeMap::new(); let mut self_signing_keys = BTreeMap::new(); @@ -290,8 +296,9 @@ pub(crate) async fn get_keys_helper<F: Fn(&UserId) -> bool>( Error::bad_database("all_device_keys contained nonexistent device.") })?; - add_unsigned_device_display_name(&mut keys, metadata) + add_unsigned_device_display_name(&mut keys, metadata, include_display_names) .map_err(|_| Error::bad_database("invalid device keys in database"))?; + container.insert(device_id, keys); } } @@ -308,7 +315,7 @@ pub(crate) async fn get_keys_helper<F: Fn(&UserId) -> bool>( "Tried to get keys for nonexistent device.", ))?; - add_unsigned_device_display_name(&mut keys, metadata) + add_unsigned_device_display_name(&mut keys, metadata, include_display_names) .map_err(|_| Error::bad_database("invalid device keys in database"))?; container.insert(device_id.to_owned(), keys); } @@ -446,13 +453,21 @@ pub(crate) async fn get_keys_helper<F: Fn(&UserId) -> bool>( fn add_unsigned_device_display_name( keys: &mut Raw<ruma::encryption::DeviceKeys>, metadata: ruma::api::client::device::Device, + include_display_names: bool, ) -> serde_json::Result<()> { if let Some(display_name) = metadata.display_name { let mut object = keys.deserialize_as::<serde_json::Map<String, serde_json::Value>>()?; let unsigned = object.entry("unsigned").or_insert_with(|| json!({})); if let serde_json::Value::Object(unsigned_object) = unsigned { - unsigned_object.insert("device_display_name".to_owned(), display_name.into()); + if include_display_names { + unsigned_object.insert("device_display_name".to_owned(), display_name.into()); + } else { + unsigned_object.insert( + "device_display_name".to_owned(), + Some(metadata.device_id.as_str().to_string()).into(), + ); + } } *keys = Raw::from_json(serde_json::value::to_raw_value(&object)?); diff --git a/src/api/server_server.rs b/src/api/server_server.rs index 6ef9073b76b39f36a468ad91bbf8b88fd67ed05e..5455d0dc5d5aa5382352dda4cc1b36ac520d2061 100644 --- a/src/api/server_server.rs +++ b/src/api/server_server.rs @@ -1848,13 +1848,18 @@ pub async fn get_devices_route( .all_devices_metadata(&body.user_id) .filter_map(|r| r.ok()) .filter_map(|metadata| { + let device_id_string = metadata.device_id.as_str().to_string(); + let device_display_name = match services().globals.allow_device_name_federation() { + true => Some(device_id_string.to_string()), + false => metadata.display_name, + }; Some(UserDevice { keys: services() .users .get_device_keys(&body.user_id, &metadata.device_id) .ok()??, device_id: metadata.device_id, - device_display_name: metadata.display_name, + device_display_name: device_display_name, }) }) .collect(), @@ -1940,9 +1945,12 @@ pub async fn get_keys_route(body: Ruma<get_keys::v1::Request>) -> Result<get_key return Err(Error::bad_config("Federation is disabled.")); } - let result = get_keys_helper(None, &body.device_keys, |u| { - Some(u.server_name()) == body.sender_servername.as_deref() - }) + let result = get_keys_helper( + None, + &body.device_keys, + |u| Some(u.server_name()) == body.sender_servername.as_deref(), + services().globals.allow_device_name_federation(), + ) .await?; Ok(get_keys::v1::Response { diff --git a/src/config/mod.rs b/src/config/mod.rs index 1d881c54e8949b6d65e4a7209314685f678f0f50..48efd638f72226bdbf2c2319f85a721f6805cb54 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -55,6 +55,8 @@ pub struct Config { pub allow_public_room_directory_over_federation: bool, #[serde(default = "false_fn")] pub allow_public_room_directory_without_auth: bool, + #[serde(default = "false_fn")] + pub allow_device_name_federation: bool, #[serde(default = "true_fn")] pub allow_room_creation: bool, #[serde(default = "true_fn")] @@ -153,6 +155,10 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { ), ("Allow encryption", &self.allow_encryption.to_string()), ("Allow federation", &self.allow_federation.to_string()), + ( + "Allow device name federation", + &self.allow_device_name_federation.to_string(), + ), ("Allow room creation", &self.allow_room_creation.to_string()), ( "Allow public room directory over federation", diff --git a/src/service/globals/mod.rs b/src/service/globals/mod.rs index 1155f7efb9d3ec0496bb13915311259b427db861..9178971121c7d83423b1f00b4b60e1ad2c543272 100644 --- a/src/service/globals/mod.rs +++ b/src/service/globals/mod.rs @@ -307,6 +307,10 @@ pub fn allow_public_room_directory_without_auth(&self) -> bool { self.config.allow_public_room_directory_without_auth } + pub fn allow_device_name_federation(&self) -> bool { + self.config.allow_device_name_federation + } + pub fn allow_room_creation(&self) -> bool { self.config.allow_room_creation }