From e2e70d6583a633cbbb71d83f5f6db19526039eef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 10 Aug 2020 15:24:22 +0200 Subject: [PATCH] crypto: Cancel timed out verifications. --- matrix_sdk_crypto/src/verification/machine.rs | 6 +++ matrix_sdk_crypto/src/verification/sas/mod.rs | 47 ++++++++++++++++--- .../src/verification/sas/sas_state.rs | 2 +- 3 files changed, 47 insertions(+), 8 deletions(-) diff --git a/matrix_sdk_crypto/src/verification/machine.rs b/matrix_sdk_crypto/src/verification/machine.rs index 7ef9e745..25bac2d2 100644 --- a/matrix_sdk_crypto/src/verification/machine.rs +++ b/matrix_sdk_crypto/src/verification/machine.rs @@ -88,6 +88,12 @@ impl VerificationMachine { pub fn garbage_collect(&self) { self.verifications .retain(|_, s| !(s.is_canceled() || s.is_done())); + + for sas in self.verifications.iter() { + if let Some(r) = sas.cancel_if_timed_out() { + self.outgoing_to_device_messages.insert(r.txn_id.clone(), r); + } + } } pub async fn receive_event( diff --git a/matrix_sdk_crypto/src/verification/sas/mod.rs b/matrix_sdk_crypto/src/verification/sas/mod.rs index 1907d438..25693d58 100644 --- a/matrix_sdk_crypto/src/verification/sas/mod.rs +++ b/matrix_sdk_crypto/src/verification/sas/mod.rs @@ -32,6 +32,7 @@ use matrix_sdk_common::{ }; use crate::{Account, CryptoStore, CryptoStoreError, Device, TrustState}; + pub use helpers::content_to_request; use sas_state::{ Accepted, Canceled, Confirmed, Created, Done, KeyReceived, MacReceived, SasState, Started, @@ -237,12 +238,31 @@ impl Sas { pub fn cancel(&self) -> Option { let mut guard = self.inner.lock().unwrap(); let sas: InnerSas = (*guard).clone(); - let (sas, content) = sas.cancel(); + let (sas, content) = sas.cancel(CancelCode::User); *guard = sas; content.map(|c| self.content_to_request(c)) } + pub(crate) fn cancel_if_timed_out(&self) -> Option { + if self.is_canceled() || self.is_done() { + None + } else if self.timed_out() { + let mut guard = self.inner.lock().unwrap(); + let sas: InnerSas = (*guard).clone(); + let (sas, content) = sas.cancel(CancelCode::Timeout); + *guard = sas; + content.map(|c| self.content_to_request(c)) + } else { + None + } + } + + /// Has the SAS verification flow timed out. + pub fn timed_out(&self) -> bool { + self.inner.lock().unwrap().is_timed_out() + } + /// Are we in a state where we can show the short auth string. pub fn can_be_presented(&self) -> bool { self.inner.lock().unwrap().can_be_presented() @@ -337,13 +357,13 @@ impl InnerSas { } } - fn cancel(self) -> (InnerSas, Option) { + fn cancel(self, code: CancelCode) -> (InnerSas, Option) { let sas = match self { - InnerSas::Created(s) => s.cancel(CancelCode::User), - InnerSas::Started(s) => s.cancel(CancelCode::User), - InnerSas::Accepted(s) => s.cancel(CancelCode::User), - InnerSas::KeyRecieved(s) => s.cancel(CancelCode::User), - InnerSas::MacReceived(s) => s.cancel(CancelCode::User), + InnerSas::Created(s) => s.cancel(code), + InnerSas::Started(s) => s.cancel(code), + InnerSas::Accepted(s) => s.cancel(code), + InnerSas::KeyRecieved(s) => s.cancel(code), + InnerSas::MacReceived(s) => s.cancel(code), _ => return (self, None), }; @@ -452,6 +472,19 @@ impl InnerSas { matches!(self, InnerSas::Canceled(_)) } + fn is_timed_out(&self) -> bool { + match self { + InnerSas::Created(s) => s.timed_out(), + InnerSas::Started(s) => s.timed_out(), + InnerSas::Canceled(s) => s.timed_out(), + InnerSas::Accepted(s) => s.timed_out(), + InnerSas::KeyRecieved(s) => s.timed_out(), + InnerSas::Confirmed(s) => s.timed_out(), + InnerSas::MacReceived(s) => s.timed_out(), + InnerSas::Done(s) => s.timed_out(), + } + } + fn verification_flow_id(&self) -> Arc { match self { InnerSas::Created(s) => s.verification_flow_id.clone(), diff --git a/matrix_sdk_crypto/src/verification/sas/sas_state.rs b/matrix_sdk_crypto/src/verification/sas/sas_state.rs index ffba64ba..a6b9e355 100644 --- a/matrix_sdk_crypto/src/verification/sas/sas_state.rs +++ b/matrix_sdk_crypto/src/verification/sas/sas_state.rs @@ -235,7 +235,7 @@ impl SasState { } /// Did our SAS verification time out. - fn timed_out(&self) -> bool { + pub fn timed_out(&self) -> bool { self.creation_time.elapsed() > MAX_AGE || self.last_event_time.elapsed() > MAX_EVENT_TIMEOUT }