mirror of
https://github.com/chatmail/core.git
synced 2026-05-22 16:26:31 +03:00
Improve dc_get_contact_encrinfo()
Return error for special IDs. Previously "No encryption." was returned for DC_CONTACT_ID_SELF. Show "No encryption." if peerstate is reset. Never talk about transport encryption: it is misleading. Even if TLS is used for client IMAP and SMTP connections, MTA-MTA connection may be unencrypted if MX does not support STARTTLS. Add a Rust test.
This commit is contained in:
@@ -5120,9 +5120,7 @@ void dc_event_unref(dc_event_t* event);
|
|||||||
/// Used to build the string returned by dc_get_contact_encrinfo().
|
/// Used to build the string returned by dc_get_contact_encrinfo().
|
||||||
#define DC_STR_E2E_AVAILABLE 25
|
#define DC_STR_E2E_AVAILABLE 25
|
||||||
|
|
||||||
/// "Transport-encryption."
|
/// DEPRECATED 2021-02-07
|
||||||
///
|
|
||||||
/// Used to build the string returned by dc_get_contact_encrinfo().
|
|
||||||
#define DC_STR_ENCR_TRANSP 27
|
#define DC_STR_ENCR_TRANSP 27
|
||||||
|
|
||||||
/// "No encryption."
|
/// "No encryption."
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ use crate::message::MessageState;
|
|||||||
use crate::mimeparser::AvatarAction;
|
use crate::mimeparser::AvatarAction;
|
||||||
use crate::param::{Param, Params};
|
use crate::param::{Param, Params};
|
||||||
use crate::peerstate::{Peerstate, PeerstateVerifiedStatus};
|
use crate::peerstate::{Peerstate, PeerstateVerifiedStatus};
|
||||||
use crate::provider::Socket;
|
|
||||||
use crate::stock::StockMessage;
|
use crate::stock::StockMessage;
|
||||||
|
|
||||||
/// An object representing a single contact in memory.
|
/// An object representing a single contact in memory.
|
||||||
@@ -687,29 +686,32 @@ impl Contact {
|
|||||||
/// of the contact and if the connection is encrypted the
|
/// of the contact and if the connection is encrypted the
|
||||||
/// fingerprints of the keys involved.
|
/// fingerprints of the keys involved.
|
||||||
pub async fn get_encrinfo(context: &Context, contact_id: u32) -> Result<String> {
|
pub async fn get_encrinfo(context: &Context, contact_id: u32) -> Result<String> {
|
||||||
|
ensure!(
|
||||||
|
contact_id > DC_CONTACT_ID_LAST_SPECIAL,
|
||||||
|
"Can not provide encryption info for special contact"
|
||||||
|
);
|
||||||
|
|
||||||
let mut ret = String::new();
|
let mut ret = String::new();
|
||||||
|
|
||||||
if let Ok(contact) = Contact::load_from_db(context, contact_id).await {
|
if let Ok(contact) = Contact::load_from_db(context, contact_id).await {
|
||||||
let peerstate = Peerstate::from_addr(context, &contact.addr).await?;
|
|
||||||
let loginparam = LoginParam::from_database(context, "configured_").await;
|
let loginparam = LoginParam::from_database(context, "configured_").await;
|
||||||
|
let peerstate = Peerstate::from_addr(context, &contact.addr).await?;
|
||||||
|
|
||||||
if peerstate.is_some()
|
if let Some(peerstate) = peerstate.filter(|peerstate| {
|
||||||
&& peerstate
|
peerstate
|
||||||
.as_ref()
|
.peek_key(PeerstateVerifiedStatus::Unverified)
|
||||||
.and_then(|p| p.peek_key(PeerstateVerifiedStatus::Unverified))
|
|
||||||
.is_some()
|
.is_some()
|
||||||
{
|
}) {
|
||||||
let peerstate = peerstate.as_ref().unwrap();
|
let stock_message = match peerstate.prefer_encrypt {
|
||||||
let p = context
|
EncryptPreference::Mutual => StockMessage::E2ePreferred,
|
||||||
.stock_str(if peerstate.prefer_encrypt == EncryptPreference::Mutual {
|
EncryptPreference::NoPreference => StockMessage::E2eAvailable,
|
||||||
StockMessage::E2ePreferred
|
EncryptPreference::Reset => StockMessage::EncrNone,
|
||||||
} else {
|
};
|
||||||
StockMessage::E2eAvailable
|
|
||||||
})
|
ret += &format!(
|
||||||
.await;
|
"{}\n{}:",
|
||||||
ret += &p;
|
context.stock_str(stock_message).await,
|
||||||
let p = context.stock_str(StockMessage::FingerPrints).await;
|
context.stock_str(StockMessage::FingerPrints).await
|
||||||
ret += &format!(" {}:", p);
|
);
|
||||||
|
|
||||||
let fingerprint_self = SignedPublicKey::load_self(context)
|
let fingerprint_self = SignedPublicKey::load_self(context)
|
||||||
.await?
|
.await?
|
||||||
@@ -740,10 +742,6 @@ impl Contact {
|
|||||||
);
|
);
|
||||||
cat_fingerprint(&mut ret, &loginparam.addr, &fingerprint_self, "");
|
cat_fingerprint(&mut ret, &loginparam.addr, &fingerprint_self, "");
|
||||||
}
|
}
|
||||||
} else if loginparam.imap.security != Socket::Plain
|
|
||||||
&& loginparam.smtp.security != Socket::Plain
|
|
||||||
{
|
|
||||||
ret += &context.stock_str(StockMessage::EncrTransp).await;
|
|
||||||
} else {
|
} else {
|
||||||
ret += &context.stock_str(StockMessage::EncrNone).await;
|
ret += &context.stock_str(StockMessage::EncrNone).await;
|
||||||
}
|
}
|
||||||
@@ -1228,6 +1226,7 @@ fn split_address_book(book: &str) -> Vec<(&str, &str)> {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
use crate::chat::send_text_msg;
|
||||||
use crate::test_utils::TestContext;
|
use crate::test_utils::TestContext;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -1614,4 +1613,47 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(id, Some(DC_CONTACT_ID_SELF));
|
assert_eq!(id, Some(DC_CONTACT_ID_SELF));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_std::test]
|
||||||
|
async fn test_contact_get_encrinfo() -> Result<()> {
|
||||||
|
let alice = TestContext::new_alice().await;
|
||||||
|
|
||||||
|
// Return error for special IDs
|
||||||
|
let encrinfo = Contact::get_encrinfo(&alice, DC_CONTACT_ID_SELF).await;
|
||||||
|
assert!(encrinfo.is_err());
|
||||||
|
let encrinfo = Contact::get_encrinfo(&alice, DC_CONTACT_ID_DEVICE).await;
|
||||||
|
assert!(encrinfo.is_err());
|
||||||
|
|
||||||
|
let (contact_bob_id, _modified) =
|
||||||
|
Contact::add_or_lookup(&alice, "Bob", "bob@example.net", Origin::ManuallyCreated)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let encrinfo = Contact::get_encrinfo(&alice, contact_bob_id).await?;
|
||||||
|
assert_eq!(encrinfo, "No encryption.");
|
||||||
|
|
||||||
|
let bob = TestContext::new_bob().await;
|
||||||
|
let chat_alice = bob
|
||||||
|
.create_chat_with_contact("Alice", "alice@example.com")
|
||||||
|
.await;
|
||||||
|
send_text_msg(&bob, chat_alice.id, "Hello".to_string()).await?;
|
||||||
|
let msg = bob.pop_sent_msg().await;
|
||||||
|
alice.recv_msg(&msg).await;
|
||||||
|
|
||||||
|
let encrinfo = Contact::get_encrinfo(&alice, contact_bob_id).await?;
|
||||||
|
assert_eq!(
|
||||||
|
encrinfo,
|
||||||
|
"End-to-end encryption preferred.
|
||||||
|
Fingerprints:
|
||||||
|
|
||||||
|
alice@example.com:
|
||||||
|
2E6F A2CB 23B5 32D7 2863
|
||||||
|
4B58 64B0 8F61 A9ED 9443
|
||||||
|
|
||||||
|
bob@example.net:
|
||||||
|
CCCB 5AA9 F6E1 141C 9431
|
||||||
|
65F1 DB18 B18C BCF7 0487"
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,9 +84,6 @@ pub enum StockMessage {
|
|||||||
#[strum(props(fallback = "End-to-end encryption available."))]
|
#[strum(props(fallback = "End-to-end encryption available."))]
|
||||||
E2eAvailable = 25,
|
E2eAvailable = 25,
|
||||||
|
|
||||||
#[strum(props(fallback = "Transport-encryption."))]
|
|
||||||
EncrTransp = 27,
|
|
||||||
|
|
||||||
#[strum(props(fallback = "No encryption."))]
|
#[strum(props(fallback = "No encryption."))]
|
||||||
EncrNone = 28,
|
EncrNone = 28,
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user