crypto: Return a deserialized ToDevice struct when we receive a sync
parent
6a30514d40
commit
17f3dbb0a0
|
@ -27,6 +27,7 @@ use std::{
|
||||||
|
|
||||||
#[cfg(feature = "encryption")]
|
#[cfg(feature = "encryption")]
|
||||||
use dashmap::DashMap;
|
use dashmap::DashMap;
|
||||||
|
#[cfg(feature = "encryption")]
|
||||||
use futures::TryStreamExt;
|
use futures::TryStreamExt;
|
||||||
use futures_timer::Delay as sleep;
|
use futures_timer::Delay as sleep;
|
||||||
use http::HeaderValue;
|
use http::HeaderValue;
|
||||||
|
@ -121,7 +122,6 @@ use matrix_sdk_common::{
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
http_client::{client_with_config, HttpClient, HttpSend},
|
http_client::{client_with_config, HttpClient, HttpSend},
|
||||||
verification_request::VerificationRequest,
|
|
||||||
Error, OutgoingRequest, Result,
|
Error, OutgoingRequest, Result,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -130,6 +130,7 @@ use crate::{
|
||||||
device::{Device, UserDevices},
|
device::{Device, UserDevices},
|
||||||
identifiers::DeviceId,
|
identifiers::DeviceId,
|
||||||
sas::Sas,
|
sas::Sas,
|
||||||
|
verification_request::VerificationRequest,
|
||||||
};
|
};
|
||||||
|
|
||||||
const DEFAULT_SYNC_TIMEOUT: Duration = Duration::from_secs(30);
|
const DEFAULT_SYNC_TIMEOUT: Duration = Duration::from_secs(30);
|
||||||
|
@ -1176,6 +1177,7 @@ impl Client {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "encryption")]
|
||||||
pub(crate) async fn room_send_helper(
|
pub(crate) async fn room_send_helper(
|
||||||
&self,
|
&self,
|
||||||
request: &RoomMessageRequest,
|
request: &RoomMessageRequest,
|
||||||
|
@ -1270,6 +1272,7 @@ impl Client {
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "encryption")]
|
||||||
async fn are_members_synced(&self, room_id: &RoomId) -> bool {
|
async fn are_members_synced(&self, room_id: &RoomId) -> bool {
|
||||||
self.base_client
|
self.base_client
|
||||||
.get_room(room_id)
|
.get_room(room_id)
|
||||||
|
|
|
@ -24,10 +24,13 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "encryption")]
|
#[cfg(feature = "encryption")]
|
||||||
use futures::StreamExt;
|
use futures::{StreamExt, TryStreamExt};
|
||||||
use futures::TryStreamExt;
|
|
||||||
use matrix_sdk_common::{
|
use matrix_sdk_common::{
|
||||||
api::r0 as api,
|
api::r0 as api,
|
||||||
|
deserialized_responses::{
|
||||||
|
AccountData, Ephemeral, InviteState, InvitedRoom, JoinedRoom, LeftRoom, MemberEvent,
|
||||||
|
Presence, Rooms, State, StrippedMemberEvent, SyncResponse, Timeline,
|
||||||
|
},
|
||||||
events::{
|
events::{
|
||||||
presence::PresenceEvent,
|
presence::PresenceEvent,
|
||||||
room::member::{MemberEventContent, MembershipState},
|
room::member::{MemberEventContent, MembershipState},
|
||||||
|
@ -41,10 +44,6 @@ use matrix_sdk_common::{
|
||||||
#[cfg(feature = "encryption")]
|
#[cfg(feature = "encryption")]
|
||||||
use matrix_sdk_common::{
|
use matrix_sdk_common::{
|
||||||
api::r0::keys::claim_keys::Request as KeysClaimRequest,
|
api::r0::keys::claim_keys::Request as KeysClaimRequest,
|
||||||
deserialized_responses::{
|
|
||||||
AccountData, Ephemeral, InviteState, InvitedRoom, JoinedRoom, LeftRoom, MemberEvent,
|
|
||||||
Presence, Rooms, State, StrippedMemberEvent, SyncResponse, Timeline,
|
|
||||||
},
|
|
||||||
events::{room::encrypted::EncryptedEventContent, AnyMessageEventContent, AnySyncMessageEvent},
|
events::{room::encrypted::EncryptedEventContent, AnyMessageEventContent, AnySyncMessageEvent},
|
||||||
identifiers::DeviceId,
|
identifiers::DeviceId,
|
||||||
locks::Mutex,
|
locks::Mutex,
|
||||||
|
@ -675,7 +674,7 @@ impl BaseClient {
|
||||||
/// * `response` - The response that we received after a successful sync.
|
/// * `response` - The response that we received after a successful sync.
|
||||||
pub async fn receive_sync_response(
|
pub async fn receive_sync_response(
|
||||||
&self,
|
&self,
|
||||||
mut response: api::sync::sync_events::Response,
|
response: api::sync::sync_events::Response,
|
||||||
) -> Result<SyncResponse> {
|
) -> Result<SyncResponse> {
|
||||||
// The server might respond multiple times with the same sync token, in
|
// The server might respond multiple times with the same sync token, in
|
||||||
// that case we already received this response and there's nothing to
|
// that case we already received this response and there's nothing to
|
||||||
|
@ -687,7 +686,7 @@ impl BaseClient {
|
||||||
let now = SystemTime::now();
|
let now = SystemTime::now();
|
||||||
|
|
||||||
#[cfg(feature = "encryption")]
|
#[cfg(feature = "encryption")]
|
||||||
{
|
let to_device = {
|
||||||
let olm = self.olm.lock().await;
|
let olm = self.olm.lock().await;
|
||||||
|
|
||||||
if let Some(o) = &*olm {
|
if let Some(o) = &*olm {
|
||||||
|
@ -695,9 +694,25 @@ impl BaseClient {
|
||||||
// decryptes to-device events, but leaves room events alone.
|
// decryptes to-device events, but leaves room events alone.
|
||||||
// This makes sure that we have the deryption keys for the room
|
// This makes sure that we have the deryption keys for the room
|
||||||
// events at hand.
|
// events at hand.
|
||||||
o.receive_sync_response(&mut response).await?;
|
o.receive_sync_response(&response).await?
|
||||||
|
} else {
|
||||||
|
response
|
||||||
|
.to_device
|
||||||
|
.events
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|e| e.deserialize().ok())
|
||||||
|
.collect::<Vec<AnyToDeviceEvent>>()
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
#[cfg(not(feature = "encryption"))]
|
||||||
|
let to_device = response
|
||||||
|
.to_device
|
||||||
|
.events
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|e| e.deserialize().ok())
|
||||||
|
.collect::<Vec<AnyToDeviceEvent>>()
|
||||||
|
.into();
|
||||||
|
|
||||||
let mut changes = StateChanges::new(response.next_batch.clone());
|
let mut changes = StateChanges::new(response.next_batch.clone());
|
||||||
let mut rooms = Rooms::default();
|
let mut rooms = Rooms::default();
|
||||||
|
@ -868,13 +883,7 @@ impl BaseClient {
|
||||||
account_data: AccountData {
|
account_data: AccountData {
|
||||||
events: changes.account_data.into_iter().map(|(_, e)| e).collect(),
|
events: changes.account_data.into_iter().map(|(_, e)| e).collect(),
|
||||||
},
|
},
|
||||||
to_device: response
|
to_device,
|
||||||
.to_device
|
|
||||||
.events
|
|
||||||
.into_iter()
|
|
||||||
.filter_map(|e| e.deserialize().ok())
|
|
||||||
.collect::<Vec<AnyToDeviceEvent>>()
|
|
||||||
.into(),
|
|
||||||
device_lists: response.device_lists,
|
device_lists: response.device_lists,
|
||||||
device_one_time_keys_count: response
|
device_one_time_keys_count: response
|
||||||
.device_one_time_keys_count
|
.device_one_time_keys_count
|
||||||
|
|
|
@ -36,7 +36,6 @@ use matrix_sdk_common::{
|
||||||
},
|
},
|
||||||
identifiers::{DeviceId, DeviceIdBox, EventEncryptionAlgorithm, RoomId, UserId},
|
identifiers::{DeviceId, DeviceIdBox, EventEncryptionAlgorithm, RoomId, UserId},
|
||||||
uuid::Uuid,
|
uuid::Uuid,
|
||||||
Raw,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -623,8 +622,7 @@ impl KeyRequestMachine {
|
||||||
&self,
|
&self,
|
||||||
sender_key: &str,
|
sender_key: &str,
|
||||||
event: &mut ToDeviceEvent<ForwardedRoomKeyToDeviceEventContent>,
|
event: &mut ToDeviceEvent<ForwardedRoomKeyToDeviceEventContent>,
|
||||||
) -> Result<(Option<Raw<AnyToDeviceEvent>>, Option<InboundGroupSession>), CryptoStoreError>
|
) -> Result<(Option<AnyToDeviceEvent>, Option<InboundGroupSession>), CryptoStoreError> {
|
||||||
{
|
|
||||||
let key_info = self.get_key_info(&event.content).await?;
|
let key_info = self.get_key_info(&event.content).await?;
|
||||||
|
|
||||||
if let Some(info) = key_info {
|
if let Some(info) = key_info {
|
||||||
|
@ -658,7 +656,7 @@ impl KeyRequestMachine {
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
Some(Raw::from(AnyToDeviceEvent::ForwardedRoomKey(event.clone()))),
|
Some(AnyToDeviceEvent::ForwardedRoomKey(event.clone())),
|
||||||
session,
|
session,
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -30,6 +30,7 @@ use matrix_sdk_common::{
|
||||||
sync::sync_events::Response as SyncResponse,
|
sync::sync_events::Response as SyncResponse,
|
||||||
},
|
},
|
||||||
assign,
|
assign,
|
||||||
|
deserialized_responses::ToDevice,
|
||||||
events::{
|
events::{
|
||||||
room::encrypted::EncryptedEventContent, room_key::RoomKeyEventContent,
|
room::encrypted::EncryptedEventContent, room_key::RoomKeyEventContent,
|
||||||
AnyMessageEventContent, AnySyncRoomEvent, AnyToDeviceEvent, SyncMessageEvent,
|
AnyMessageEventContent, AnySyncRoomEvent, AnyToDeviceEvent, SyncMessageEvent,
|
||||||
|
@ -573,7 +574,7 @@ impl OlmMachine {
|
||||||
// don't want them to be able to do silly things with it. Handling
|
// don't want them to be able to do silly things with it. Handling
|
||||||
// events modifies them and returns a modified one, so replace it
|
// events modifies them and returns a modified one, so replace it
|
||||||
// here if we get one.
|
// here if we get one.
|
||||||
decrypted.event = event;
|
decrypted.deserialized_event = Some(event);
|
||||||
decrypted.inbound_group_session = group_session;
|
decrypted.inbound_group_session = group_session;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -586,7 +587,7 @@ impl OlmMachine {
|
||||||
sender_key: &str,
|
sender_key: &str,
|
||||||
signing_key: &str,
|
signing_key: &str,
|
||||||
event: &mut ToDeviceEvent<RoomKeyEventContent>,
|
event: &mut ToDeviceEvent<RoomKeyEventContent>,
|
||||||
) -> OlmResult<(Option<Raw<AnyToDeviceEvent>>, Option<InboundGroupSession>)> {
|
) -> OlmResult<(Option<AnyToDeviceEvent>, Option<InboundGroupSession>)> {
|
||||||
match event.content.algorithm {
|
match event.content.algorithm {
|
||||||
EventEncryptionAlgorithm::MegolmV1AesSha2 => {
|
EventEncryptionAlgorithm::MegolmV1AesSha2 => {
|
||||||
let session_key = GroupSessionKey(mem::take(&mut event.content.session_key));
|
let session_key = GroupSessionKey(mem::take(&mut event.content.session_key));
|
||||||
|
@ -597,7 +598,7 @@ impl OlmMachine {
|
||||||
&event.content.room_id,
|
&event.content.room_id,
|
||||||
session_key,
|
session_key,
|
||||||
)?;
|
)?;
|
||||||
let event = Raw::from(AnyToDeviceEvent::RoomKey(event.clone()));
|
let event = AnyToDeviceEvent::RoomKey(event.clone());
|
||||||
Ok((Some(event), Some(session)))
|
Ok((Some(event), Some(session)))
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -697,7 +698,7 @@ impl OlmMachine {
|
||||||
async fn handle_decrypted_to_device_event(
|
async fn handle_decrypted_to_device_event(
|
||||||
&self,
|
&self,
|
||||||
decrypted: &OlmDecryptionInfo,
|
decrypted: &OlmDecryptionInfo,
|
||||||
) -> OlmResult<(Option<Raw<AnyToDeviceEvent>>, Option<InboundGroupSession>)> {
|
) -> OlmResult<(Option<AnyToDeviceEvent>, Option<InboundGroupSession>)> {
|
||||||
let event = match decrypted.event.deserialize() {
|
let event = match decrypted.event.deserialize() {
|
||||||
Ok(e) => e,
|
Ok(e) => e,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
@ -719,7 +720,7 @@ impl OlmMachine {
|
||||||
.await?),
|
.await?),
|
||||||
_ => {
|
_ => {
|
||||||
warn!("Received an unexpected encrypted to-device event");
|
warn!("Received an unexpected encrypted to-device event");
|
||||||
Ok((None, None))
|
Ok((Some(event), None))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -774,7 +775,7 @@ impl OlmMachine {
|
||||||
/// * `response` - The sync latest sync response.
|
/// * `response` - The sync latest sync response.
|
||||||
///
|
///
|
||||||
/// [`decrypt_room_event`]: #method.decrypt_room_event
|
/// [`decrypt_room_event`]: #method.decrypt_room_event
|
||||||
pub async fn receive_sync_response(&self, response: &mut SyncResponse) -> OlmResult<()> {
|
pub async fn receive_sync_response(&self, response: &SyncResponse) -> OlmResult<ToDevice> {
|
||||||
// Remove verification objects that have expired or are done.
|
// Remove verification objects that have expired or are done.
|
||||||
self.verification_machine.garbage_collect();
|
self.verification_machine.garbage_collect();
|
||||||
|
|
||||||
|
@ -794,7 +795,9 @@ impl OlmMachine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for event_result in &mut response.to_device.events {
|
let mut events = Vec::new();
|
||||||
|
|
||||||
|
for event_result in &response.to_device.events {
|
||||||
let mut event = if let Ok(e) = event_result.deserialize() {
|
let mut event = if let Ok(e) = event_result.deserialize() {
|
||||||
e
|
e
|
||||||
} else {
|
} else {
|
||||||
|
@ -849,7 +852,9 @@ impl OlmMachine {
|
||||||
changes.inbound_group_sessions.push(group_session);
|
changes.inbound_group_sessions.push(group_session);
|
||||||
}
|
}
|
||||||
|
|
||||||
*event_result = decrypted.event;
|
if let Some(e) = decrypted.deserialized_event {
|
||||||
|
event = e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
AnyToDeviceEvent::RoomKeyRequest(e) => {
|
AnyToDeviceEvent::RoomKeyRequest(e) => {
|
||||||
self.key_request_machine.receive_incoming_key_request(e)
|
self.key_request_machine.receive_incoming_key_request(e)
|
||||||
|
@ -864,6 +869,8 @@ impl OlmMachine {
|
||||||
}
|
}
|
||||||
_ => continue,
|
_ => continue,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
events.push(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
let changed_sessions = self
|
let changed_sessions = self
|
||||||
|
@ -873,7 +880,9 @@ impl OlmMachine {
|
||||||
|
|
||||||
changes.sessions.extend(changed_sessions);
|
changes.sessions.extend(changed_sessions);
|
||||||
|
|
||||||
Ok(self.store.save_changes(changes).await?)
|
self.store.save_changes(changes).await?;
|
||||||
|
|
||||||
|
Ok(ToDevice { events })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decrypt an event from a room timeline.
|
/// Decrypt an event from a room timeline.
|
||||||
|
@ -1661,7 +1670,7 @@ pub(crate) mod test {
|
||||||
.save_inbound_group_sessions(&[decrypted.inbound_group_session.unwrap()])
|
.save_inbound_group_sessions(&[decrypted.inbound_group_session.unwrap()])
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let event = decrypted.event.deserialize().unwrap();
|
let event = decrypted.deserialized_event.unwrap();
|
||||||
|
|
||||||
if let AnyToDeviceEvent::RoomKey(event) = event {
|
if let AnyToDeviceEvent::RoomKey(event) = event {
|
||||||
assert_eq!(&event.sender, alice.user_id());
|
assert_eq!(&event.sender, alice.user_id());
|
||||||
|
|
|
@ -91,6 +91,7 @@ impl SessionType {
|
||||||
pub struct OlmDecryptionInfo {
|
pub struct OlmDecryptionInfo {
|
||||||
pub session: SessionType,
|
pub session: SessionType,
|
||||||
pub message_hash: OlmMessageHash,
|
pub message_hash: OlmMessageHash,
|
||||||
|
pub deserialized_event: Option<AnyToDeviceEvent>,
|
||||||
pub event: Raw<AnyToDeviceEvent>,
|
pub event: Raw<AnyToDeviceEvent>,
|
||||||
pub signing_key: String,
|
pub signing_key: String,
|
||||||
pub sender_key: String,
|
pub sender_key: String,
|
||||||
|
@ -179,6 +180,7 @@ impl Account {
|
||||||
message_hash,
|
message_hash,
|
||||||
event,
|
event,
|
||||||
signing_key,
|
signing_key,
|
||||||
|
deserialized_event: None,
|
||||||
sender_key: content.sender_key.clone(),
|
sender_key: content.sender_key.clone(),
|
||||||
inbound_group_session: None,
|
inbound_group_session: None,
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue