From 5f4dee96e63c9269ec2344c7600dcc393f758ef6 Mon Sep 17 00:00:00 2001 From: Matti Viljanen Date: Wed, 21 Aug 2024 12:31:09 +0300 Subject: [PATCH 1/2] Add sending message request response messages --- libsignal-service/src/sender.rs | 51 +++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/libsignal-service/src/sender.rs b/libsignal-service/src/sender.rs index d0da55659..c5bf090e9 100644 --- a/libsignal-service/src/sender.rs +++ b/libsignal-service/src/sender.rs @@ -13,8 +13,10 @@ use crate::{ cipher::{get_preferred_protocol_address, ServiceCipher}, content::ContentBody, proto::{ - attachment_pointer::AttachmentIdentifier, - attachment_pointer::Flags as AttachmentPointerFlags, sync_message, + attachment_pointer::{ + AttachmentIdentifier, Flags as AttachmentPointerFlags, + }, + sync_message::{self, message_request_response}, AttachmentPointer, SyncMessage, }, push_service::*, @@ -691,6 +693,51 @@ where Ok(()) } + /// Send `MessageRequestResponse` synchronization message with either a recipient ACI or a GroupV2 ID + #[tracing::instrument(skip(self))] + pub async fn send_message_request_response( + &mut self, + recipient: &ServiceAddress, + thread_aci: Option<&ServiceAddress>, + group_id: Option<&[u8; 64]>, + action: message_request_response::Type, + ) -> Result<(), MessageSenderError> { + match (&thread_aci, &group_id) { + (Some(_), Some(_)) => { + return Err(MessageSenderError::ProtocolError( + SignalProtocolError::InvalidArgument( + "Both ACI and GroupV2 ID provided".to_string(), + ), + )) + }, + (None, None) => { + return Err(MessageSenderError::ProtocolError( + SignalProtocolError::InvalidArgument( + "No ACI or GroupV2 ID provided".to_string(), + ), + )) + }, + _ => {}, + } + let msg = SyncMessage { + message_request_response: Some( + sync_message::MessageRequestResponse { + thread_aci: thread_aci.map(|a| a.uuid.to_string()), + group_id: group_id.map(Vec::from), + r#type: Some(action.into()), + }, + ), + ..SyncMessage::with_padding() + }; + + let ts = Utc::now().timestamp_millis() as u64; + tracing::info!("Sending message request response: {:?}", msg); + self.send_message(recipient, None, msg, ts, false, false) + .await?; + + Ok(()) + } + #[tracing::instrument(level = "trace", skip(self))] fn create_pni_signature( &mut self, From 07c1850272f0cefc37c90df54d6b906b84e4377c Mon Sep 17 00:00:00 2001 From: Matti Viljanen Date: Sat, 24 Aug 2024 10:00:15 +0300 Subject: [PATCH 2/2] Use stronger types for message request responses --- libsignal-service/src/sender.rs | 66 ++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/libsignal-service/src/sender.rs b/libsignal-service/src/sender.rs index c5bf090e9..f0c8fcfd7 100644 --- a/libsignal-service/src/sender.rs +++ b/libsignal-service/src/sender.rs @@ -8,6 +8,8 @@ use libsignal_protocol::{ use rand::{CryptoRng, Rng}; use tracing::{error, info, trace}; use tracing_futures::Instrument; +use uuid::Uuid; +use zkgroup::GROUP_IDENTIFIER_LEN; use crate::{ cipher::{get_preferred_protocol_address, ServiceCipher}, @@ -16,7 +18,9 @@ use crate::{ attachment_pointer::{ AttachmentIdentifier, Flags as AttachmentPointerFlags, }, - sync_message::{self, message_request_response}, + sync_message::{ + self, message_request_response, MessageRequestResponse, + }, AttachmentPointer, SyncMessage, }, push_service::*, @@ -125,6 +129,14 @@ pub enum MessageSenderError { NotFound { addr: ServiceAddress }, } +pub type GroupV2Id = [u8; GROUP_IDENTIFIER_LEN]; + +#[derive(Debug)] +pub enum ThreadIdentifier { + Aci(Uuid), + Group(GroupV2Id), +} + impl MessageSender where Service: PushService, @@ -698,40 +710,42 @@ where pub async fn send_message_request_response( &mut self, recipient: &ServiceAddress, - thread_aci: Option<&ServiceAddress>, - group_id: Option<&[u8; 64]>, + thread: &ThreadIdentifier, action: message_request_response::Type, ) -> Result<(), MessageSenderError> { - match (&thread_aci, &group_id) { - (Some(_), Some(_)) => { - return Err(MessageSenderError::ProtocolError( - SignalProtocolError::InvalidArgument( - "Both ACI and GroupV2 ID provided".to_string(), - ), - )) + let message_request_response = Some(match thread { + ThreadIdentifier::Aci(aci) => { + tracing::debug!( + "sending message request response {:?} for recipient {:?}", + action, + aci + ); + MessageRequestResponse { + thread_aci: Some(aci.to_string()), + group_id: None, + r#type: Some(action.into()), + } }, - (None, None) => { - return Err(MessageSenderError::ProtocolError( - SignalProtocolError::InvalidArgument( - "No ACI or GroupV2 ID provided".to_string(), - ), - )) + ThreadIdentifier::Group(id) => { + tracing::debug!( + "sending message request response {:?} for group {:?}", + action, + id + ); + MessageRequestResponse { + thread_aci: None, + group_id: Some(id.to_vec()), + r#type: Some(action.into()), + } }, - _ => {}, - } + }); + let msg = SyncMessage { - message_request_response: Some( - sync_message::MessageRequestResponse { - thread_aci: thread_aci.map(|a| a.uuid.to_string()), - group_id: group_id.map(Vec::from), - r#type: Some(action.into()), - }, - ), + message_request_response, ..SyncMessage::with_padding() }; let ts = Utc::now().timestamp_millis() as u64; - tracing::info!("Sending message request response: {:?}", msg); self.send_message(recipient, None, msg, ts, false, false) .await?;