feat: send vc- prefix instead of vg- in Secure-Join where accepted

This way we always send `Secure-Join: vc-request`,
even when joining the group,
and it is not visible to the server if we setup a new contact
or join a group/channel.
This commit is contained in:
link2xt
2026-01-07 16:07:44 +00:00
parent 13dafa46b5
commit fe4a1e72af
3 changed files with 17 additions and 34 deletions

View File

@@ -484,19 +484,10 @@ pub(crate) async fn handle_securejoin_handshake(
) )
.await?; .await?;
let prefix = mime_message
.get_header(HeaderDef::SecureJoin)
.and_then(|step| step.get(..2))
.unwrap_or("vc");
// Alice -> Bob // Alice -> Bob
send_alice_handshake_msg( send_alice_handshake_msg(context, autocrypt_contact_id, "vc-auth-required")
context,
autocrypt_contact_id,
&format!("{prefix}-auth-required"),
)
.await .await
.context("failed sending auth-required handshake message")?; .context("Failed sending auth-required handshake message")?;
Ok(HandshakeMessage::Done) Ok(HandshakeMessage::Done)
} }
SecureJoinStep::AuthRequired => { SecureJoinStep::AuthRequired => {

View File

@@ -27,7 +27,7 @@ use crate::tools::{smeared_time, time};
/// If Bob already has Alice's key, he sends `AUTH` token /// If Bob already has Alice's key, he sends `AUTH` token
/// and forgets about the invite. /// and forgets about the invite.
/// If Bob does not yet have Alice's key, he sends `vc-request` /// If Bob does not yet have Alice's key, he sends `vc-request`
/// or `vg-request` message and stores a row in the `bobstate` table /// message and stores a row in the `bobstate` table
/// so he can check Alice's key against the fingerprint /// so he can check Alice's key against the fingerprint
/// and send `AUTH` token later. /// and send `AUTH` token later.
/// ///
@@ -301,14 +301,14 @@ pub(crate) async fn send_handshake_message(
) -> Result<()> { ) -> Result<()> {
let mut msg = Message { let mut msg = Message {
viewtype: Viewtype::Text, viewtype: Viewtype::Text,
text: step.body_text(invite), text: step.body_text(),
hidden: true, hidden: true,
..Default::default() ..Default::default()
}; };
msg.param.set_cmd(SystemMessage::SecurejoinMessage); msg.param.set_cmd(SystemMessage::SecurejoinMessage);
// Sends the step in Secure-Join header. // Sends the step in Secure-Join header.
msg.param.set(Param::Arg, step.securejoin_header(invite)); msg.param.set(Param::Arg, step.securejoin_header());
match step { match step {
BobHandshakeMsg::Request => { BobHandshakeMsg::Request => {
@@ -345,9 +345,9 @@ pub(crate) async fn send_handshake_message(
/// Identifies the SecureJoin handshake messages Bob can send. /// Identifies the SecureJoin handshake messages Bob can send.
pub(crate) enum BobHandshakeMsg { pub(crate) enum BobHandshakeMsg {
/// vc-request or vg-request /// vc-request
Request, Request,
/// vc-request-with-auth or vg-request-with-auth /// vc-request-with-auth
RequestWithAuth, RequestWithAuth,
} }
@@ -357,8 +357,8 @@ impl BobHandshakeMsg {
/// This text has no significance to the protocol, but would be visible if users see /// This text has no significance to the protocol, but would be visible if users see
/// this email message directly, e.g. when accessing their email without using /// this email message directly, e.g. when accessing their email without using
/// DeltaChat. /// DeltaChat.
fn body_text(&self, invite: &QrInvite) -> String { fn body_text(&self) -> String {
format!("Secure-Join: {}", self.securejoin_header(invite)) format!("Secure-Join: {}", self.securejoin_header())
} }
/// Returns the `Secure-Join` header value. /// Returns the `Secure-Join` header value.
@@ -366,18 +366,10 @@ impl BobHandshakeMsg {
/// This identifies the step this message is sending information about. Most protocol /// This identifies the step this message is sending information about. Most protocol
/// steps include additional information into other headers, see /// steps include additional information into other headers, see
/// [`send_handshake_message`] for these. /// [`send_handshake_message`] for these.
fn securejoin_header(&self, invite: &QrInvite) -> &'static str { fn securejoin_header(&self) -> &'static str {
match self { match self {
Self::Request => match invite { Self::Request => "vc-request",
QrInvite::Contact { .. } => "vc-request", Self::RequestWithAuth => "vc-request-with-auth",
QrInvite::Group { .. } => "vg-request",
QrInvite::Broadcast { .. } => "vg-request",
},
Self::RequestWithAuth => match invite {
QrInvite::Contact { .. } => "vc-request-with-auth",
QrInvite::Group { .. } => "vg-request-with-auth",
QrInvite::Broadcast { .. } => "vg-request-with-auth",
},
} }
} }
} }
@@ -447,7 +439,7 @@ async fn joining_chat_id(
/// This has an `From<JoinerProgress> for usize` impl yielding numbers between 0 and a 1000 /// This has an `From<JoinerProgress> for usize` impl yielding numbers between 0 and a 1000
/// which can be shown as a progress bar. /// which can be shown as a progress bar.
pub(crate) enum JoinerProgress { pub(crate) enum JoinerProgress {
/// vg-vc-request-with-auth sent. /// vc-request-with-auth sent.
/// ///
/// Typically shows as "alice@addr verified, introducing myself." /// Typically shows as "alice@addr verified, introducing myself."
RequestWithAuthSent, RequestWithAuthSent,

View File

@@ -457,7 +457,7 @@ async fn test_secure_join() -> Result<()> {
); );
let msg = alice.parse_msg(&sent).await; let msg = alice.parse_msg(&sent).await;
assert!(!msg.was_encrypted()); assert!(!msg.was_encrypted());
assert_eq!(msg.get_header(HeaderDef::SecureJoin).unwrap(), "vg-request"); assert_eq!(msg.get_header(HeaderDef::SecureJoin).unwrap(), "vc-request");
assert!(msg.get_header(HeaderDef::SecureJoinInvitenumber).is_some()); assert!(msg.get_header(HeaderDef::SecureJoinInvitenumber).is_some());
assert!(!msg.header_exists(HeaderDef::AutoSubmitted)); assert!(!msg.header_exists(HeaderDef::AutoSubmitted));
@@ -478,7 +478,7 @@ async fn test_secure_join() -> Result<()> {
assert!(msg.was_encrypted()); assert!(msg.was_encrypted());
assert_eq!( assert_eq!(
msg.get_header(HeaderDef::SecureJoin).unwrap(), msg.get_header(HeaderDef::SecureJoin).unwrap(),
"vg-auth-required" "vc-auth-required"
); );
tcm.section("Step 4: Bob receives vg-auth-required, sends vg-request-with-auth"); tcm.section("Step 4: Bob receives vg-auth-required, sends vg-request-with-auth");
@@ -516,7 +516,7 @@ async fn test_secure_join() -> Result<()> {
assert!(msg.was_encrypted()); assert!(msg.was_encrypted());
assert_eq!( assert_eq!(
msg.get_header(HeaderDef::SecureJoin).unwrap(), msg.get_header(HeaderDef::SecureJoin).unwrap(),
"vg-request-with-auth" "vc-request-with-auth"
); );
assert!(msg.get_header(HeaderDef::SecureJoinAuth).is_some()); assert!(msg.get_header(HeaderDef::SecureJoinAuth).is_some());
let bob_fp = self_fingerprint(&bob).await?; let bob_fp = self_fingerprint(&bob).await?;