diff --git a/bindings/matrix-sdk-ffi/Cargo.toml b/bindings/matrix-sdk-ffi/Cargo.toml index c8900f9a4..8dec0adf4 100644 --- a/bindings/matrix-sdk-ffi/Cargo.toml +++ b/bindings/matrix-sdk-ffi/Cargo.toml @@ -42,11 +42,38 @@ uniffi = { workspace = true } url = "2.2.2" zeroize = { workspace = true } - [target.'cfg(target_os = "android")'.dependencies] log-panics = { version = "2", features = ["with-backtrace"]} tracing-android = "0.2.0" -matrix-sdk = { path = "../../crates/matrix-sdk", default-features = false, features = ["anyhow", "experimental-timeline", "e2e-encryption", "sled", "markdown", "experimental-sliding-sync", "socks", "rustls-tls"], version = "0.6.0" } [target.'cfg(not(target_os = "android"))'.dependencies] -matrix-sdk = { path = "../../crates/matrix-sdk", features = ["anyhow", "experimental-timeline", "markdown", "experimental-sliding-sync", "socks"], version = "0.6.0" } +tracing = { workspace = true } +tracing-subscriber = { version = "0.3", features = ["env-filter"] } + +[target.'cfg(target_os = "android")'.dependencies.matrix-sdk] +path = "../../crates/matrix-sdk" +default-features = false +features = [ + "anyhow", + "experimental-sliding-sync", + "experimental-timeline", + "e2e-encryption", + "markdown", + "sled", + "socks", + "rustls-tls", +] + +[target.'cfg(not(target_os = "android"))'.dependencies.matrix-sdk] +path = "../../crates/matrix-sdk" +default-features = false +features = [ + "anyhow", + "experimental-sliding-sync", + "experimental-timeline", + "e2e-encryption", + "markdown", + "native-tls", + "sled", + "socks", +] diff --git a/crates/matrix-sdk-base/Cargo.toml b/crates/matrix-sdk-base/Cargo.toml index 4bcfd5dc0..ec210d304 100644 --- a/crates/matrix-sdk-base/Cargo.toml +++ b/crates/matrix-sdk-base/Cargo.toml @@ -20,6 +20,7 @@ default = [] e2e-encryption = ["dep:matrix-sdk-crypto"] js = ["matrix-sdk-common/js", "matrix-sdk-crypto?/js", "ruma/js", "matrix-sdk-store-encryption/js"] qrcode = ["matrix-sdk-crypto?/qrcode"] +automatic-room-key-forwarding = ["matrix-sdk-crypto?/automatic-room-key-forwarding"] experimental-sliding-sync = ["ruma/unstable-msc3575"] # helpers for testing features build upon this @@ -35,7 +36,7 @@ futures-core = "0.3.21" futures-util = { workspace = true } http = { workspace = true, optional = true } matrix-sdk-common = { version = "0.6.0", path = "../matrix-sdk-common" } -matrix-sdk-crypto = { version = "0.6.0", path = "../matrix-sdk-crypto", optional = true } +matrix-sdk-crypto = { version = "0.6.0", path = "../matrix-sdk-crypto", optional = true, default-features = false } matrix-sdk-store-encryption = { version = "0.2.0", path = "../matrix-sdk-store-encryption" } matrix-sdk-test = { version = "0.6.0", path = "../../testing/matrix-sdk-test", optional = true } once_cell = { workspace = true } diff --git a/crates/matrix-sdk-crypto/Cargo.toml b/crates/matrix-sdk-crypto/Cargo.toml index f28c117f1..4ac80533f 100644 --- a/crates/matrix-sdk-crypto/Cargo.toml +++ b/crates/matrix-sdk-crypto/Cargo.toml @@ -15,7 +15,8 @@ version = "0.6.0" rustdoc-args = ["--cfg", "docsrs"] [features] -default = [] +default = ["automatic-room-key-forwarding"] +automatic-room-key-forwarding = [] js = ["ruma/js", "vodozemac/js"] qrcode = ["dep:matrix-sdk-qrcode"] backups_v1 = ["dep:olm-rs", "dep:bs58"] diff --git a/crates/matrix-sdk-crypto/src/gossiping/machine.rs b/crates/matrix-sdk-crypto/src/gossiping/machine.rs index 05c6adf81..ee77ba127 100644 --- a/crates/matrix-sdk-crypto/src/gossiping/machine.rs +++ b/crates/matrix-sdk-crypto/src/gossiping/machine.rs @@ -20,8 +20,12 @@ // If we don't trust the device store an object that remembers the request and // let the users introspect that object. -use std::{collections::BTreeMap, sync::Arc}; +use std::{ + collections::BTreeMap, + sync::{atomic::AtomicBool, Arc}, +}; +use atomic::Ordering; use dashmap::{mapref::entry::Entry, DashMap, DashSet}; use ruma::{ api::client::keys::claim_keys::v3::Request as KeysClaimRequest, @@ -34,10 +38,10 @@ use ruma::{ use tracing::{debug, info, trace, warn}; use vodozemac::{megolm::SessionOrdering, Curve25519PublicKey}; -use super::{GossipRequest, KeyForwardDecision, RequestEvent, RequestInfo, SecretInfo, WaitQueue}; +use super::{GossipRequest, RequestEvent, RequestInfo, SecretInfo, WaitQueue}; use crate::{ error::{EventError, OlmError, OlmResult}, - olm::{InboundGroupSession, Session, ShareState}, + olm::{InboundGroupSession, Session}, requests::{OutgoingRequest, ToDeviceRequest}, session_manager::GroupSessionCache, store::{Changes, CryptoStoreError, SecretImportError, Store}, @@ -45,7 +49,7 @@ use crate::{ forwarded_room_key::ForwardedRoomKeyContent, olm_v1::{DecryptedForwardedRoomKeyEvent, DecryptedSecretSendEvent}, room::encrypted::EncryptedEvent, - room_key_request::{Action, RequestedKeyInfo, RoomKeyRequestEvent}, + room_key_request::RoomKeyRequestEvent, secret_send::SecretSendContent, EventType, }, @@ -57,11 +61,13 @@ pub(crate) struct GossipMachine { user_id: Arc, device_id: Arc, store: Store, + #[cfg(feature = "automatic-room-key-forwarding")] outbound_group_sessions: GroupSessionCache, outgoing_requests: Arc>, incoming_key_requests: Arc>, wait_queue: WaitQueue, users_for_key_claim: Arc>>, + room_key_forwarding_enabled: Arc, } impl GossipMachine { @@ -69,21 +75,35 @@ impl GossipMachine { user_id: Arc, device_id: Arc, store: Store, - outbound_group_sessions: GroupSessionCache, + #[allow(unused)] outbound_group_sessions: GroupSessionCache, users_for_key_claim: Arc>>, ) -> Self { + let room_key_forwarding_enabled = + AtomicBool::new(cfg!(feature = "automatic-room-key-forwarding")).into(); + Self { user_id, device_id, store, + #[cfg(feature = "automatic-room-key-forwarding")] outbound_group_sessions, outgoing_requests: Default::default(), incoming_key_requests: Default::default(), wait_queue: WaitQueue::new(), users_for_key_claim, + room_key_forwarding_enabled, } } + #[cfg(feature = "automatic-room-key-forwarding")] + pub fn toggle_room_key_forwarding(&self, enabled: bool) { + self.room_key_forwarding_enabled.store(enabled, Ordering::SeqCst) + } + + pub fn is_room_key_forwarding_enabled(&self) -> bool { + self.room_key_forwarding_enabled.load(Ordering::SeqCst) + } + /// Load stored outgoing requests that were not yet sent out. async fn load_outgoing_requests(&self) -> Result, CryptoStoreError> { Ok(self @@ -171,8 +191,11 @@ impl GossipMachine { let event = item.value(); if let Some(s) = match event { + #[cfg(feature = "automatic-room-key-forwarding")] RequestEvent::KeyShare(e) => self.handle_key_request(e).await?, RequestEvent::Secret(e) => self.handle_secret_request(e).await?, + #[cfg(not(feature = "automatic-room-key-forwarding"))] + _ => None, } { changed_sessions.push(s); } @@ -312,6 +335,7 @@ impl GossipMachine { /// given `Device`, in that case we're going to queue up an /// `/keys/claim` request to be sent out and retry once the 1-to-1 Olm /// session has been established. + #[cfg(feature = "automatic-room-key-forwarding")] async fn try_to_forward_room_key( &self, event: &RoomKeyRequestEvent, @@ -358,11 +382,14 @@ impl GossipMachine { /// Answer a room key request after we found the matching /// `InboundGroupSession`. + #[cfg(feature = "automatic-room-key-forwarding")] async fn answer_room_key_request( &self, event: &RoomKeyRequestEvent, session: InboundGroupSession, ) -> OlmResult> { + use super::KeyForwardDecision; + let device = self.store.get_device(&event.sender, &event.content.requesting_device_id).await?; @@ -403,6 +430,7 @@ impl GossipMachine { } } + #[cfg(feature = "automatic-room-key-forwarding")] async fn handle_supported_key_request( &self, event: &RoomKeyRequestEvent, @@ -427,27 +455,38 @@ impl GossipMachine { } /// Handle a single incoming key request. + #[cfg(feature = "automatic-room-key-forwarding")] async fn handle_key_request(&self, event: &RoomKeyRequestEvent) -> OlmResult> { - match &event.content.action { - Action::Request(info) => match info { - RequestedKeyInfo::MegolmV1AesSha2(i) => { - self.handle_supported_key_request(event, &i.room_id, &i.session_id).await - } - #[cfg(feature = "experimental-algorithms")] - RequestedKeyInfo::MegolmV2AesSha2(i) => { - self.handle_supported_key_request(event, &i.room_id, &i.session_id).await - } - RequestedKeyInfo::Unknown(i) => { - debug!( - sender = ?event.sender, - algorithm = ?i.algorithm, - "Received a room key request for a unsupported algorithm" - ); - Ok(None) - } - }, - // We ignore cancellations here since there's nothing to serve. - Action::Cancellation => Ok(None), + use crate::types::events::room_key_request::{Action, RequestedKeyInfo}; + + if self.room_key_forwarding_enabled.load(Ordering::SeqCst) { + match &event.content.action { + Action::Request(info) => match info { + RequestedKeyInfo::MegolmV1AesSha2(i) => { + self.handle_supported_key_request(event, &i.room_id, &i.session_id).await + } + #[cfg(feature = "experimental-algorithms")] + RequestedKeyInfo::MegolmV2AesSha2(i) => { + self.handle_supported_key_request(event, &i.room_id, &i.session_id).await + } + RequestedKeyInfo::Unknown(i) => { + debug!( + sender = ?event.sender, + algorithm = ?i.algorithm, + "Received a room key request for a unsupported algorithm" + ); + Ok(None) + } + }, + // We ignore cancellations here since there's nothing to serve. + Action::Cancellation => Ok(None), + } + } else { + debug!( + sender = ?event.sender, + "Received a room key request, but room key forwarding has been turned off" + ); + Ok(None) } } @@ -476,6 +515,7 @@ impl GossipMachine { Ok(used_session) } + #[cfg(feature = "automatic-room-key-forwarding")] async fn forward_room_key( &self, session: &InboundGroupSession, @@ -533,11 +573,16 @@ impl GossipMachine { /// i. /// - `Err(x)`: Should *refuse* to share the session. `x` is the reason for /// the refusal. + + #[cfg(feature = "automatic-room-key-forwarding")] async fn should_share_key( &self, device: &Device, session: &InboundGroupSession, - ) -> Result, KeyForwardDecision> { + ) -> Result, super::KeyForwardDecision> { + use super::KeyForwardDecision; + use crate::olm::ShareState; + let outbound_session = self .outbound_group_sessions .get_with_id(session.room_id(), session.session_id()) @@ -575,20 +620,21 @@ impl GossipMachine { /// /// * `key_info` - The info of our key request containing information about /// the key we wish to request. + #[cfg(feature = "automatic-room-key-forwarding")] async fn should_request_key(&self, key_info: &SecretInfo) -> Result { - let request = self.store.get_secret_request_by_info(key_info).await?; + if self.room_key_forwarding_enabled.load(Ordering::SeqCst) { + let request = self.store.get_secret_request_by_info(key_info).await?; - // Don't send out duplicate requests, users can re-request them if they - // think a second request might succeed. - if request.is_none() { - let devices = self.store.get_user_devices(self.user_id()).await?; + // Don't send out duplicate requests, users can re-request them if they + // think a second request might succeed. + if request.is_none() { + let devices = self.store.get_user_devices(self.user_id()).await?; - // Devices will only respond to key requests if the devices are - // verified, if the device isn't verified by us it's unlikely that - // we're verified by them either. Don't request keys if there isn't - // at least one verified device. - if devices.is_any_verified() { - Ok(true) + // Devices will only respond to key requests if the devices are + // verified, if the device isn't verified by us it's unlikely that + // we're verified by them either. Don't request keys if there isn't + // at least one verified device. + Ok(devices.is_any_verified()) } else { Ok(false) } @@ -681,6 +727,7 @@ impl GossipMachine { /// * `room_id` - The id of the room where the key is used in. /// /// * `event` - The event for which we would like to request the room key. + #[cfg(feature = "automatic-room-key-forwarding")] pub async fn create_outgoing_key_request( &self, room_id: &RoomId, @@ -989,6 +1036,7 @@ impl GossipMachine { mod tests { use std::sync::Arc; + #[cfg(feature = "automatic-room-key-forwarding")] use assert_matches::assert_matches; use dashmap::DashMap; use matrix_sdk_common::locks::Mutex; @@ -997,35 +1045,40 @@ mod tests { device_id, event_id, events::{ secret::request::{RequestAction, SecretName, ToDeviceSecretRequestEventContent}, - AnyToDeviceEventContent, ToDeviceEvent as RumaToDeviceEvent, + ToDeviceEvent as RumaToDeviceEvent, }, room_id, serde::Raw, user_id, DeviceId, RoomId, UserId, }; + #[cfg(feature = "automatic-room-key-forwarding")] use serde::{de::DeserializeOwned, Serialize}; use serde_json::json; - use super::{GossipMachine, KeyForwardDecision}; + use super::GossipMachine; + #[cfg(feature = "automatic-room-key-forwarding")] use crate::{ - identities::{LocalTrust, ReadOnlyDevice}, - olm::{Account, OutboundGroupSession, PrivateCrossSigningIdentity, ReadOnlyAccount}, - session_manager::GroupSessionCache, - store::{Changes, IntoCryptoStore, MemoryStore, Store}, + gossiping::KeyForwardDecision, + olm::OutboundGroupSession, + store::Changes, types::{ events::{ - forwarded_room_key::ForwardedRoomKeyContent, - olm_v1::{AnyDecryptedOlmEvent, DecryptedOlmV1Event}, - room::encrypted::{ - EncryptedEvent, EncryptedToDeviceEvent, RoomEncryptedEventContent, - }, - EventType, ToDeviceEvent, + forwarded_room_key::ForwardedRoomKeyContent, olm_v1::AnyDecryptedOlmEvent, + olm_v1::DecryptedOlmV1Event, room::encrypted::EncryptedToDeviceEvent, EventType, + ToDeviceEvent, }, EventEncryptionAlgorithm, }, - verification::VerificationMachine, EncryptionSettings, OutgoingRequest, OutgoingRequests, }; + use crate::{ + identities::{LocalTrust, ReadOnlyDevice}, + olm::{Account, PrivateCrossSigningIdentity, ReadOnlyAccount}, + session_manager::GroupSessionCache, + store::{IntoCryptoStore, MemoryStore, Store}, + types::events::room::encrypted::{EncryptedEvent, RoomEncryptedEventContent}, + verification::VerificationMachine, + }; fn alice_id() -> &'static UserId { user_id!("@alice:example.org") @@ -1063,6 +1116,7 @@ mod tests { ReadOnlyAccount::new(alice_id(), alice2_device_id()) } + #[cfg(feature = "automatic-room-key-forwarding")] fn test_gossip_machine(user_id: &UserId) -> GossipMachine { let user_id = Arc::from(user_id); let device_id = DeviceId::new(); @@ -1107,6 +1161,7 @@ mod tests { ) } + #[cfg(feature = "automatic-room-key-forwarding")] async fn machines_for_key_share( other_machine_owner: &UserId, create_sessions: bool, @@ -1148,9 +1203,10 @@ mod tests { .await .unwrap(); + bob_machine.store.save_inbound_group_sessions(&[inbound_group_session]).await.unwrap(); + let content = group_session.encrypt(json!({}), "m.dummy").await; let event = wrap_encrypted_content(bob_machine.user_id(), content); - bob_machine.store.save_inbound_group_sessions(&[inbound_group_session]).await.unwrap(); // Alice wants to request the outbound group session from bob. assert!( @@ -1172,10 +1228,11 @@ mod tests { (alice_machine, alice_account, group_session, bob_machine) } + #[cfg(feature = "automatic-room-key-forwarding")] fn extract_content<'a>( recipient: &UserId, request: &'a OutgoingRequest, - ) -> &'a Raw { + ) -> &'a Raw { request .request() .to_device() @@ -1204,6 +1261,7 @@ mod tests { } } + #[cfg(feature = "automatic-room-key-forwarding")] fn request_to_event( recipient: &UserId, sender: &UserId, @@ -1250,6 +1308,7 @@ mod tests { } #[async_test] + #[cfg(feature = "automatic-room-key-forwarding")] async fn create_key_request() { let machine = get_machine().await; let account = account(); @@ -1281,6 +1340,7 @@ mod tests { } #[async_test] + #[cfg(feature = "automatic-room-key-forwarding")] async fn receive_forwarded_key() { let machine = get_machine().await; let account = account(); @@ -1383,6 +1443,7 @@ mod tests { } #[async_test] + #[cfg(feature = "automatic-room-key-forwarding")] async fn should_share_key_test() { let machine = get_machine().await; let account = account(); @@ -1497,6 +1558,7 @@ mod tests { assert_matches!(machine.should_share_key(&own_device, &other_inbound).await, Ok(None)); } + #[cfg(feature = "automatic-room-key-forwarding")] async fn key_share_cycle(algorithm: EventEncryptionAlgorithm) { let (alice_machine, alice_account, group_session, bob_machine) = machines_for_key_share(alice_id(), true, algorithm).await; @@ -1556,6 +1618,7 @@ mod tests { } #[async_test] + #[cfg(feature = "automatic-room-key-forwarding")] async fn reject_forward_from_another_user() { let (alice_machine, alice_account, group_session, bob_machine) = machines_for_key_share(bob_id(), true, EventEncryptionAlgorithm::MegolmV1AesSha2).await; @@ -1605,12 +1668,13 @@ mod tests { } #[async_test] + #[cfg(feature = "automatic-room-key-forwarding")] async fn key_share_cycle_megolm_v1() { key_share_cycle(EventEncryptionAlgorithm::MegolmV1AesSha2).await; } - #[cfg(feature = "experimental-algorithms")] #[async_test] + #[cfg(all(feature = "experimental-algorithms", feature = "automatic-room-key-forwarding"))] async fn key_share_cycle_megolm_v2() { key_share_cycle(EventEncryptionAlgorithm::MegolmV2AesSha2).await; } @@ -1686,6 +1750,7 @@ mod tests { } #[async_test] + #[cfg(feature = "automatic-room-key-forwarding")] async fn key_share_cycle_without_session() { let (alice_machine, alice_account, group_session, bob_machine) = machines_for_key_share(alice_id(), false, EventEncryptionAlgorithm::MegolmV1AesSha2) diff --git a/crates/matrix-sdk-crypto/src/gossiping/mod.rs b/crates/matrix-sdk-crypto/src/gossiping/mod.rs index f0487d371..3ed63c02e 100644 --- a/crates/matrix-sdk-crypto/src/gossiping/mod.rs +++ b/crates/matrix-sdk-crypto/src/gossiping/mod.rs @@ -32,8 +32,6 @@ use ruma::{ DeviceId, OwnedDeviceId, OwnedTransactionId, OwnedUserId, TransactionId, UserId, }; use serde::{Deserialize, Serialize}; -use thiserror::Error; -use tracing::error; use crate::{ requests::{OutgoingRequest, ToDeviceRequest}, @@ -44,7 +42,8 @@ use crate::{ }; /// An error describing why a key share request won't be honored. -#[derive(Debug, Clone, Error, PartialEq, Eq)] +#[cfg(feature = "automatic-room-key-forwarding")] +#[derive(Debug, Clone, thiserror::Error, PartialEq, Eq)] pub enum KeyForwardDecision { /// The key request is from a device that we don't own, we're only sharing /// sessions that we know the requesting device already was supposed to get. @@ -302,7 +301,7 @@ impl WaitQueue { } } - #[cfg(test)] + #[cfg(all(test, feature = "automatic-room-key-forwarding"))] fn is_empty(&self) -> bool { self.requests_ids_waiting.is_empty() && self.requests_waiting_for_session.is_empty() } diff --git a/crates/matrix-sdk-crypto/src/machine.rs b/crates/matrix-sdk-crypto/src/machine.rs index 1a02f379d..275e1caed 100644 --- a/crates/matrix-sdk-crypto/src/machine.rs +++ b/crates/matrix-sdk-crypto/src/machine.rs @@ -47,10 +47,7 @@ use tracing::{ field::{debug, display}, info, instrument, warn, Span, }; -use vodozemac::{ - megolm::{DecryptionError, SessionOrdering}, - Curve25519PublicKey, Ed25519Signature, -}; +use vodozemac::{megolm::SessionOrdering, Curve25519PublicKey, Ed25519Signature}; #[cfg(feature = "backups_v1")] use crate::backups::BackupMachine; @@ -326,6 +323,21 @@ impl OlmMachine { self.store.tracked_users().await } + /// Enable or disable room key forwarding. + /// + /// Room key forwarding allows the device to request room keys that it might + /// have missend in the original share using `m.room_key_request` + /// events. + #[cfg(feature = "automatic-room-key-forwarding")] + pub fn toggle_room_key_forwarding(&self, enable: bool) { + self.key_request_machine.toggle_room_key_forwarding(enable) + } + + /// Is room key forwarding enabled? + pub fn is_room_key_forwarding_enabled(&self) -> bool { + self.key_request_machine.is_room_key_forwarding_enabled() + } + /// Get the outgoing requests that need to be sent out. /// /// This returns a list of [`OutgoingRequest`]. Those requests need to be @@ -1227,9 +1239,12 @@ impl OlmMachine { let result = self.decrypt_megolm_events(room_id, &event, &content).await; if let Err(e) = &result { + #[cfg(feature = "automatic-room-key-forwarding")] match e { MegolmError::MissingRoomKey - | MegolmError::Decryption(DecryptionError::UnknownMessageIndex(_, _)) => { + | MegolmError::Decryption( + vodozemac::megolm::DecryptionError::UnknownMessageIndex(_, _), + ) => { self.key_request_machine.create_outgoing_key_request(room_id, &event).await?; } _ => {} @@ -2131,6 +2146,7 @@ pub(crate) mod tests { } #[async_test] + #[cfg(feature = "automatic-room-key-forwarding")] async fn test_query_ratcheted_key() { let (alice, bob) = get_machine_pair_with_setup_sessions().await; let room_id = room_id!("!test:example.org"); @@ -2185,7 +2201,7 @@ pub(crate) mod tests { let decrypt_error = bob.decrypt_room_event(&room_event, room_id).await.unwrap_err(); - if let MegolmError::Decryption(vodo_error) = decrypt_error { + if let crate::MegolmError::Decryption(vodo_error) = decrypt_error { if let vodozemac::megolm::DecryptionError::UnknownMessageIndex(_, _) = vodo_error { // check that key has been requested let outgoing_to_devices = diff --git a/crates/matrix-sdk-crypto/src/session_manager/group_sessions.rs b/crates/matrix-sdk-crypto/src/session_manager/group_sessions.rs index af8783a67..9d177b6bd 100644 --- a/crates/matrix-sdk-crypto/src/session_manager/group_sessions.rs +++ b/crates/matrix-sdk-crypto/src/session_manager/group_sessions.rs @@ -95,6 +95,7 @@ impl GroupSessionCache { /// /// This is the same as [get_or_load()](#method.get_or_load) but it will /// filter out the session if it doesn't match the given session id. + #[cfg(feature = "automatic-room-key-forwarding")] pub async fn get_with_id( &self, room_id: &RoomId, diff --git a/crates/matrix-sdk/Cargo.toml b/crates/matrix-sdk/Cargo.toml index fff94ed01..89ae57e03 100644 --- a/crates/matrix-sdk/Cargo.toml +++ b/crates/matrix-sdk/Cargo.toml @@ -18,6 +18,7 @@ rustdoc-args = ["--cfg", "docsrs"] [features] default = [ "e2e-encryption", + "automatic-room-key-forwarding", "sled", "native-tls", ] @@ -25,6 +26,7 @@ testing = [] e2e-encryption = [ "matrix-sdk-base/e2e-encryption", + "matrix-sdk-base/automatic-room-key-forwarding", "matrix-sdk-sled?/crypto-store", # activate crypto-store on sled if given "matrix-sdk-indexeddb?/e2e-encryption", # activate on indexeddb if given ] @@ -34,6 +36,7 @@ sled = ["dep:matrix-sdk-sled", "matrix-sdk-sled?/state-store"] indexeddb = ["dep:matrix-sdk-indexeddb"] qrcode = ["e2e-encryption", "matrix-sdk-base/qrcode"] +automatic-room-key-forwarding = ["e2e-encryption", "matrix-sdk-base/automatic-room-key-forwarding"] markdown = ["ruma/markdown"] native-tls = ["reqwest/native-tls"] rustls-tls = ["reqwest/rustls-tls"] diff --git a/xtask/src/ci.rs b/xtask/src/ci.rs index 65f264b16..44cc61bf9 100644 --- a/xtask/src/ci.rs +++ b/xtask/src/ci.rs @@ -235,6 +235,7 @@ fn run_crypto_tests() -> Result<()> { "rustup run stable cargo clippy -p matrix-sdk-crypto --features=backups_v1 -- -D warnings" ) .run()?; + cmd!("rustup run stable cargo nextest run -p matrix-sdk-crypto --no-default-features").run()?; cmd!("rustup run stable cargo nextest run -p matrix-sdk-crypto --features=backups_v1").run()?; cmd!("rustup run stable cargo test --doc -p matrix-sdk-crypto --features=backups_v1").run()?; cmd!(