crypto: Cancel timed out verifications.

master
Damir Jelić 2020-08-10 15:24:22 +02:00
parent c305b5052b
commit e2e70d6583
3 changed files with 47 additions and 8 deletions

View File

@ -88,6 +88,12 @@ impl VerificationMachine {
pub fn garbage_collect(&self) { pub fn garbage_collect(&self) {
self.verifications self.verifications
.retain(|_, s| !(s.is_canceled() || s.is_done())); .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( pub async fn receive_event(

View File

@ -32,6 +32,7 @@ use matrix_sdk_common::{
}; };
use crate::{Account, CryptoStore, CryptoStoreError, Device, TrustState}; use crate::{Account, CryptoStore, CryptoStoreError, Device, TrustState};
pub use helpers::content_to_request; pub use helpers::content_to_request;
use sas_state::{ use sas_state::{
Accepted, Canceled, Confirmed, Created, Done, KeyReceived, MacReceived, SasState, Started, Accepted, Canceled, Confirmed, Created, Done, KeyReceived, MacReceived, SasState, Started,
@ -237,12 +238,31 @@ impl Sas {
pub fn cancel(&self) -> Option<OwnedToDeviceRequest> { pub fn cancel(&self) -> Option<OwnedToDeviceRequest> {
let mut guard = self.inner.lock().unwrap(); let mut guard = self.inner.lock().unwrap();
let sas: InnerSas = (*guard).clone(); let sas: InnerSas = (*guard).clone();
let (sas, content) = sas.cancel(); let (sas, content) = sas.cancel(CancelCode::User);
*guard = sas; *guard = sas;
content.map(|c| self.content_to_request(c)) content.map(|c| self.content_to_request(c))
} }
pub(crate) fn cancel_if_timed_out(&self) -> Option<OwnedToDeviceRequest> {
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. /// Are we in a state where we can show the short auth string.
pub fn can_be_presented(&self) -> bool { pub fn can_be_presented(&self) -> bool {
self.inner.lock().unwrap().can_be_presented() self.inner.lock().unwrap().can_be_presented()
@ -337,13 +357,13 @@ impl InnerSas {
} }
} }
fn cancel(self) -> (InnerSas, Option<AnyToDeviceEventContent>) { fn cancel(self, code: CancelCode) -> (InnerSas, Option<AnyToDeviceEventContent>) {
let sas = match self { let sas = match self {
InnerSas::Created(s) => s.cancel(CancelCode::User), InnerSas::Created(s) => s.cancel(code),
InnerSas::Started(s) => s.cancel(CancelCode::User), InnerSas::Started(s) => s.cancel(code),
InnerSas::Accepted(s) => s.cancel(CancelCode::User), InnerSas::Accepted(s) => s.cancel(code),
InnerSas::KeyRecieved(s) => s.cancel(CancelCode::User), InnerSas::KeyRecieved(s) => s.cancel(code),
InnerSas::MacReceived(s) => s.cancel(CancelCode::User), InnerSas::MacReceived(s) => s.cancel(code),
_ => return (self, None), _ => return (self, None),
}; };
@ -452,6 +472,19 @@ impl InnerSas {
matches!(self, InnerSas::Canceled(_)) 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<String> { fn verification_flow_id(&self) -> Arc<String> {
match self { match self {
InnerSas::Created(s) => s.verification_flow_id.clone(), InnerSas::Created(s) => s.verification_flow_id.clone(),

View File

@ -235,7 +235,7 @@ impl<S: Clone> SasState<S> {
} }
/// Did our SAS verification time out. /// 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 self.creation_time.elapsed() > MAX_AGE || self.last_event_time.elapsed() > MAX_EVENT_TIMEOUT
} }