crypto: Allow QR code verifications to get into the cancelled state as well.

master
Damir Jelić 2021-06-28 15:28:30 +02:00
parent 63659c9604
commit ee6b804804
2 changed files with 40 additions and 4 deletions

View File

@ -287,10 +287,17 @@ impl VerificationMachine {
verification.receive_cancel(event.sender(), c); verification.receive_cancel(event.sender(), c);
} }
if let Some(sas) = self.get_sas(event.sender(), flow_id.as_str()) { if let Some(verification) =
self.get_verification(event.sender(), flow_id.as_str())
{
match verification {
Verification::SasV1(sas) => {
// This won't produce an outgoing content // This won't produce an outgoing content
let _ = sas.receive_any_event(event.sender(), &content); let _ = sas.receive_any_event(event.sender(), &content);
} }
Verification::QrV1(qr) => qr.receive_cancel(event.sender(), c),
}
}
} }
AnyVerificationContent::Ready(c) => { AnyVerificationContent::Ready(c) => {
if let Some(request) = self.get_request(event.sender(), flow_id.as_str()) { if let Some(request) = self.get_request(event.sender(), flow_id.as_str()) {

View File

@ -36,9 +36,10 @@ use ruma::{
DeviceId, DeviceIdBox, DeviceKeyAlgorithm, RoomId, UserId, DeviceId, DeviceIdBox, DeviceKeyAlgorithm, RoomId, UserId,
}; };
use thiserror::Error; use thiserror::Error;
use tracing::trace;
use super::{ use super::{
event_enums::{DoneContent, OutgoingContent, OwnedStartContent, StartContent}, event_enums::{CancelContent, DoneContent, OutgoingContent, OwnedStartContent, StartContent},
Cancelled, Done, FlowId, IdentitiesBeingVerified, VerificationResult, Cancelled, Done, FlowId, IdentitiesBeingVerified, VerificationResult,
}; };
use crate::{ use crate::{
@ -393,6 +394,28 @@ impl QrVerification {
} }
} }
pub(crate) fn receive_cancel(&self, sender: &UserId, content: &CancelContent<'_>) {
if sender == self.other_user_id() {
let mut state = self.state.lock().unwrap();
let new_state = match &*state {
InnerState::Created(s) => s.clone().into_cancelled(content),
InnerState::Scanned(s) => s.clone().into_cancelled(content),
InnerState::Confirmed(s) => s.clone().into_cancelled(content),
InnerState::Reciprocated(s) => s.clone().into_cancelled(content),
InnerState::Done(_) | InnerState::Cancelled(_) => return,
};
trace!(
sender = sender.as_str(),
code = content.cancel_code().as_str(),
"Cancelling a QR verification, other user has cancelled"
);
*state = InnerState::Cancelled(new_state);
}
}
fn generate_secret() -> String { fn generate_secret() -> String {
let mut shared_secret = [0u8; SECRET_SIZE]; let mut shared_secret = [0u8; SECRET_SIZE];
getrandom::getrandom(&mut shared_secret) getrandom::getrandom(&mut shared_secret)
@ -609,6 +632,12 @@ struct QrState<S: Clone> {
state: S, state: S,
} }
impl<S: Clone> QrState<S> {
pub fn into_cancelled(self, content: &CancelContent<'_>) -> QrState<Cancelled> {
QrState { state: Cancelled::new(false, content.cancel_code().to_owned()) }
}
}
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
struct Created { struct Created {
secret: String, secret: String,