mirror of
https://github.com/chatmail/core.git
synced 2026-05-02 04:46:29 +03:00
check_verified_properties(): Don't ignore fails of Peerstate::set_verified()
- Return Result from set_verified() so that it can't be missed. - Pass Fingerprint to set_verified() by value to avoid cloning it inside. This optimises out an extra clone() if we already have a value that can be moved at the caller side. However, this may add an extra clone() if set_verified() fails, but let's not optimise the fail scenario.
This commit is contained in:
@@ -17,7 +17,7 @@ use crate::message::Message;
|
|||||||
use crate::mimeparser::SystemMessage;
|
use crate::mimeparser::SystemMessage;
|
||||||
use crate::sql::Sql;
|
use crate::sql::Sql;
|
||||||
use crate::stock_str;
|
use crate::stock_str;
|
||||||
use anyhow::{Context as _, Result};
|
use anyhow::{Context as _, Error, Result};
|
||||||
use num_traits::FromPrimitive;
|
use num_traits::FromPrimitive;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -369,43 +369,48 @@ impl Peerstate {
|
|||||||
/// verifier:
|
/// verifier:
|
||||||
/// The address which verifies the given contact
|
/// The address which verifies the given contact
|
||||||
/// If we are verifying the contact, use that contacts address
|
/// If we are verifying the contact, use that contacts address
|
||||||
/// Returns whether the value of the key has changed
|
|
||||||
pub fn set_verified(
|
pub fn set_verified(
|
||||||
&mut self,
|
&mut self,
|
||||||
which_key: PeerstateKeyType,
|
which_key: PeerstateKeyType,
|
||||||
fingerprint: &Fingerprint,
|
fingerprint: Fingerprint,
|
||||||
verified: PeerstateVerifiedStatus,
|
verified: PeerstateVerifiedStatus,
|
||||||
verifier: String,
|
verifier: String,
|
||||||
) -> bool {
|
) -> Result<()> {
|
||||||
if verified == PeerstateVerifiedStatus::BidirectVerified {
|
if verified == PeerstateVerifiedStatus::BidirectVerified {
|
||||||
match which_key {
|
match which_key {
|
||||||
PeerstateKeyType::PublicKey => {
|
PeerstateKeyType::PublicKey => {
|
||||||
if self.public_key_fingerprint.is_some()
|
if self.public_key_fingerprint.is_some()
|
||||||
&& self.public_key_fingerprint.as_ref().unwrap() == fingerprint
|
&& self.public_key_fingerprint.as_ref().unwrap() == &fingerprint
|
||||||
{
|
{
|
||||||
self.verified_key = self.public_key.clone();
|
self.verified_key = self.public_key.clone();
|
||||||
self.verified_key_fingerprint = self.public_key_fingerprint.clone();
|
self.verified_key_fingerprint = Some(fingerprint);
|
||||||
self.verifier = Some(verifier);
|
self.verifier = Some(verifier);
|
||||||
true
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
false
|
Err(Error::msg(format!(
|
||||||
|
"{} is not peer's public key fingerprint",
|
||||||
|
fingerprint,
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PeerstateKeyType::GossipKey => {
|
PeerstateKeyType::GossipKey => {
|
||||||
if self.gossip_key_fingerprint.is_some()
|
if self.gossip_key_fingerprint.is_some()
|
||||||
&& self.gossip_key_fingerprint.as_ref().unwrap() == fingerprint
|
&& self.gossip_key_fingerprint.as_ref().unwrap() == &fingerprint
|
||||||
{
|
{
|
||||||
self.verified_key = self.gossip_key.clone();
|
self.verified_key = self.gossip_key.clone();
|
||||||
self.verified_key_fingerprint = self.gossip_key_fingerprint.clone();
|
self.verified_key_fingerprint = Some(fingerprint);
|
||||||
self.verifier = Some(verifier);
|
self.verifier = Some(verifier);
|
||||||
true
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
false
|
Err(Error::msg(format!(
|
||||||
|
"{} is not peer's gossip key fingerprint",
|
||||||
|
fingerprint,
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
false
|
Err(Error::msg("BidirectVerified required"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2178,10 +2178,10 @@ async fn check_verified_properties(
|
|||||||
if let Some(fp) = fp {
|
if let Some(fp) = fp {
|
||||||
peerstate.set_verified(
|
peerstate.set_verified(
|
||||||
PeerstateKeyType::GossipKey,
|
PeerstateKeyType::GossipKey,
|
||||||
&fp,
|
fp,
|
||||||
PeerstateVerifiedStatus::BidirectVerified,
|
PeerstateVerifiedStatus::BidirectVerified,
|
||||||
contact.get_addr().to_owned(),
|
contact.get_addr().to_owned(),
|
||||||
);
|
)?;
|
||||||
peerstate.save_to_db(&context.sql).await?;
|
peerstate.save_to_db(&context.sql).await?;
|
||||||
is_verified = true;
|
is_verified = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -415,7 +415,7 @@ pub(crate) async fn handle_securejoin_handshake(
|
|||||||
.await?
|
.await?
|
||||||
.get_addr()
|
.get_addr()
|
||||||
.to_owned();
|
.to_owned();
|
||||||
if mark_peer_as_verified(context, &fingerprint, contact_addr)
|
if mark_peer_as_verified(context, fingerprint.clone(), contact_addr)
|
||||||
.await
|
.await
|
||||||
.is_err()
|
.is_err()
|
||||||
{
|
{
|
||||||
@@ -613,28 +613,23 @@ pub(crate) async fn observe_securejoin_on_other_device(
|
|||||||
return Ok(HandshakeMessage::Ignore);
|
return Ok(HandshakeMessage::Ignore);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if peerstate.set_verified(
|
if let Err(err) = peerstate.set_verified(
|
||||||
PeerstateKeyType::GossipKey,
|
PeerstateKeyType::GossipKey,
|
||||||
&fingerprint,
|
fingerprint,
|
||||||
PeerstateVerifiedStatus::BidirectVerified,
|
PeerstateVerifiedStatus::BidirectVerified,
|
||||||
addr,
|
addr,
|
||||||
) {
|
) {
|
||||||
peerstate.prefer_encrypt = EncryptPreference::Mutual;
|
|
||||||
peerstate.save_to_db(&context.sql).await.unwrap_or_default();
|
|
||||||
} else {
|
|
||||||
could_not_establish_secure_connection(
|
could_not_establish_secure_connection(
|
||||||
context,
|
context,
|
||||||
contact_id,
|
contact_id,
|
||||||
info_chat_id(context, contact_id).await?,
|
info_chat_id(context, contact_id).await?,
|
||||||
&format!(
|
&format!("Could not mark peer as verified at step {}: {}", step, err),
|
||||||
"Could not mark peer as verified for fingerprint {} at step {}",
|
|
||||||
fingerprint.hex(),
|
|
||||||
step,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
return Ok(HandshakeMessage::Ignore);
|
return Ok(HandshakeMessage::Ignore);
|
||||||
}
|
}
|
||||||
|
peerstate.prefer_encrypt = EncryptPreference::Mutual;
|
||||||
|
peerstate.save_to_db(&context.sql).await.unwrap_or_default();
|
||||||
} else if let Some(fingerprint) =
|
} else if let Some(fingerprint) =
|
||||||
mime_message.get_header(HeaderDef::SecureJoinFingerprint)
|
mime_message.get_header(HeaderDef::SecureJoinFingerprint)
|
||||||
{
|
{
|
||||||
@@ -643,7 +638,7 @@ pub(crate) async fn observe_securejoin_on_other_device(
|
|||||||
let fingerprint = fingerprint.parse()?;
|
let fingerprint = fingerprint.parse()?;
|
||||||
if mark_peer_as_verified(
|
if mark_peer_as_verified(
|
||||||
context,
|
context,
|
||||||
&fingerprint,
|
fingerprint,
|
||||||
Contact::load_from_db(context, contact_id)
|
Contact::load_from_db(context, contact_id)
|
||||||
.await?
|
.await?
|
||||||
.get_addr()
|
.get_addr()
|
||||||
@@ -715,25 +710,25 @@ async fn could_not_establish_secure_connection(
|
|||||||
|
|
||||||
async fn mark_peer_as_verified(
|
async fn mark_peer_as_verified(
|
||||||
context: &Context,
|
context: &Context,
|
||||||
fingerprint: &Fingerprint,
|
fingerprint: Fingerprint,
|
||||||
verifier: String,
|
verifier: String,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
if let Some(ref mut peerstate) = Peerstate::from_fingerprint(context, fingerprint).await? {
|
if let Some(ref mut peerstate) = Peerstate::from_fingerprint(context, &fingerprint).await? {
|
||||||
if peerstate.set_verified(
|
if let Err(err) = peerstate.set_verified(
|
||||||
PeerstateKeyType::PublicKey,
|
PeerstateKeyType::PublicKey,
|
||||||
fingerprint,
|
fingerprint,
|
||||||
PeerstateVerifiedStatus::BidirectVerified,
|
PeerstateVerifiedStatus::BidirectVerified,
|
||||||
verifier,
|
verifier,
|
||||||
) {
|
) {
|
||||||
peerstate.prefer_encrypt = EncryptPreference::Mutual;
|
error!(context, "Could not mark peer as verified: {}", err);
|
||||||
peerstate.save_to_db(&context.sql).await.unwrap_or_default();
|
return Err(err);
|
||||||
return Ok(());
|
|
||||||
}
|
}
|
||||||
|
peerstate.prefer_encrypt = EncryptPreference::Mutual;
|
||||||
|
peerstate.save_to_db(&context.sql).await.unwrap_or_default();
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
bail!("no peerstate in db for fingerprint {}", fingerprint.hex());
|
||||||
}
|
}
|
||||||
bail!(
|
|
||||||
"could not mark peer as verified for fingerprint {}",
|
|
||||||
fingerprint.hex()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ******************************************************************************
|
/* ******************************************************************************
|
||||||
|
|||||||
@@ -368,7 +368,7 @@ impl BobState {
|
|||||||
}
|
}
|
||||||
mark_peer_as_verified(
|
mark_peer_as_verified(
|
||||||
context,
|
context,
|
||||||
self.invite.fingerprint(),
|
self.invite.fingerprint().clone(),
|
||||||
mime_message.from.addr.to_string(),
|
mime_message.from.addr.to_string(),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|||||||
Reference in New Issue
Block a user