libsignal_service/
proto.rs

1#![allow(clippy::all)]
2
3use rand::{CryptoRng, Rng};
4include!(concat!(env!("OUT_DIR"), "/signalservice.rs"));
5include!(concat!(env!("OUT_DIR"), "/signal.rs"));
6
7impl WebSocketRequestMessage {
8    /// Equivalent of
9    /// `SignalServiceMessagePipe::isSignalServiceEnvelope(WebSocketMessage)`.
10    pub fn is_signal_service_envelope(&self) -> bool {
11        self.verb.as_deref() == Some("PUT")
12            && self.path.as_deref() == Some("/api/v1/message")
13    }
14
15    pub fn is_queue_empty(&self) -> bool {
16        self.verb.as_deref() == Some("PUT")
17            && self.path.as_deref() == Some("/api/v1/queue/empty")
18    }
19
20    /// Equivalent of
21    /// `SignalServiceMessagePipe::isSignalKeyEncrypted(WebSocketMessage)`.
22    pub fn is_signal_key_encrypted(&self) -> bool {
23        if self.headers.is_empty() {
24            return true;
25        }
26
27        for header in &self.headers {
28            let parts: Vec<_> = header.split(':').collect();
29            if parts.len() != 2 {
30                tracing::warn!(
31                    "Got a weird header: {:?}, split in {:?}",
32                    header,
33                    parts
34                );
35                continue;
36            }
37
38            if parts[0].trim().eq_ignore_ascii_case("X-Signal-Key")
39                && parts[1].trim().eq_ignore_ascii_case("false")
40            {
41                return false;
42            }
43        }
44
45        true
46    }
47}
48
49impl WebSocketResponseMessage {
50    /// Equivalent of
51    /// `SignalServiceMessagePipe::isSignalServiceEnvelope(WebSocketMessage)`.
52    pub fn from_request(msg: &WebSocketRequestMessage) -> Self {
53        if msg.is_signal_service_envelope() || msg.is_queue_empty() {
54            WebSocketResponseMessage {
55                id: msg.id,
56                status: Some(200),
57                message: Some("OK".to_string()),
58                ..Default::default()
59            }
60        } else {
61            WebSocketResponseMessage {
62                id: msg.id,
63                status: Some(400),
64                message: Some("Unknown".to_string()),
65                ..Default::default()
66            }
67        }
68    }
69}
70
71impl SyncMessage {
72    pub fn with_padding<R: Rng + CryptoRng>(csprng: &mut R) -> Self {
73        let random_size = csprng.gen_range(1..=512);
74        let mut padding: Vec<u8> = vec![0; random_size];
75        csprng.fill_bytes(&mut padding);
76
77        Self {
78            padding: Some(padding),
79            ..Default::default()
80        }
81    }
82}