sardine/messages/
srd_message.rs

1use messages::*;
2use srd_errors::SrdError;
3use std::io::{Read, Write};
4use Result;
5
6pub trait Message {
7    fn read_from<R: Read>(reader: &mut R) -> Result<Self>
8        where
9            Self: Sized;
10    fn write_to<W: Write>(&self, writer: &mut W) -> Result<()>;
11}
12
13#[derive(Debug, PartialEq, Eq, Clone)]
14pub enum SrdMessage {
15    Initiate(SrdHeader, SrdInitiate),
16    Offer(SrdHeader, SrdOffer),
17    Accept(SrdHeader, SrdAccept),
18    Confirm(SrdHeader, SrdConfirm),
19    Delegate(SrdHeader, SrdDelegate),
20}
21
22impl SrdMessage {
23    #[allow(dead_code)]
24    pub fn msg_type(&self) -> u8 {
25        match self {
26            SrdMessage::Initiate(hdr, _) => hdr.msg_type(),
27            SrdMessage::Offer(hdr, _) => hdr.msg_type(),
28            SrdMessage::Accept(hdr, _) => hdr.msg_type(),
29            SrdMessage::Confirm(hdr, _) => hdr.msg_type(),
30            SrdMessage::Delegate(hdr, _) => hdr.msg_type(),
31        }
32    }
33
34    pub fn signature(&self) -> u32 {
35        match self {
36            SrdMessage::Initiate(hdr, _) => hdr.signature(),
37            SrdMessage::Offer(hdr, _) => hdr.signature(),
38            SrdMessage::Accept(hdr, _) => hdr.signature(),
39            SrdMessage::Confirm(hdr, _) => hdr.signature(),
40            SrdMessage::Delegate(hdr, _) => hdr.signature(),
41        }
42    }
43
44    pub fn seq_num(&self) -> u8 {
45        match self {
46            SrdMessage::Initiate(hdr, _) => hdr.seq_num(),
47            SrdMessage::Offer(hdr, _) => hdr.seq_num(),
48            SrdMessage::Accept(hdr, _) => hdr.seq_num(),
49            SrdMessage::Confirm(hdr, _) => hdr.seq_num(),
50            SrdMessage::Delegate(hdr, _) => hdr.seq_num(),
51        }
52    }
53
54    pub fn has_cbt(&self) -> bool {
55        match self {
56            SrdMessage::Initiate(hdr, _) => hdr.has_cbt(),
57            SrdMessage::Offer(hdr, _) => hdr.has_cbt(),
58            SrdMessage::Accept(hdr, _) => hdr.has_cbt(),
59            SrdMessage::Confirm(hdr, _) => hdr.has_cbt(),
60            SrdMessage::Delegate(hdr, _) => hdr.has_cbt(),
61        }
62    }
63
64    pub fn has_mac(&self) -> bool {
65        match self {
66            SrdMessage::Initiate(hdr, _) => hdr.has_mac(),
67            SrdMessage::Offer(hdr, _) => hdr.has_mac(),
68            SrdMessage::Accept(hdr, _) => hdr.has_mac(),
69            SrdMessage::Confirm(hdr, _) => hdr.has_mac(),
70            SrdMessage::Delegate(hdr, _) => hdr.has_mac(),
71        }
72    }
73
74    pub fn has_skip(&self) -> bool {
75        match self {
76            SrdMessage::Initiate(hdr, _) => hdr.has_skip(),
77            SrdMessage::Offer(hdr, _) => hdr.has_skip(),
78            SrdMessage::Accept(hdr, _) => hdr.has_skip(),
79            SrdMessage::Confirm(hdr, _) => hdr.has_skip(),
80            SrdMessage::Delegate(hdr, _) => hdr.has_skip(),
81        }
82    }
83
84    pub fn mac(&self) -> Option<&[u8]> {
85        match self {
86            SrdMessage::Initiate(_, _) => None,
87            SrdMessage::Offer(_, _) => None,
88            SrdMessage::Accept(_, accept) => Some(accept.mac()),
89            SrdMessage::Confirm(_, confirm) => Some(confirm.mac()),
90            SrdMessage::Delegate(_, delegate) => Some(delegate.mac()),
91        }
92    }
93
94    pub fn set_mac(&mut self, mac: &[u8]) -> Result<()> {
95        match self {
96            SrdMessage::Initiate(_, _) => Err(SrdError::Proto("No mac on an initiate message".to_owned())),
97            SrdMessage::Offer(_, _) => Err(SrdError::Proto("No mac on an offer message".to_owned())),
98            SrdMessage::Accept(_, ref mut accept) => Ok(accept.set_mac(mac)),
99            SrdMessage::Confirm(_, ref mut confirm) => Ok(confirm.set_mac(mac)),
100            SrdMessage::Delegate(_, ref mut delegate) => Ok(delegate.set_mac(mac)),
101        }
102    }
103
104    pub fn set_skip(&mut self) {
105        match self {
106            SrdMessage::Initiate(hdr, _) => hdr.add_skip_flag(),
107            SrdMessage::Offer(hdr, _) => hdr.add_skip_flag(),
108            SrdMessage::Accept(hdr, _) => hdr.add_skip_flag(),
109            SrdMessage::Confirm(hdr, _) =>hdr.add_skip_flag(),
110            _ => {},
111        }
112    }
113
114    pub fn validate(self) -> Result<Self> {
115        match &self {
116            SrdMessage::Initiate(hdr, initiate) => {
117                // No MAC in that message
118                hdr.validate_flags(false)?;
119
120                // Key size supported : 256, 512 or 1024
121                match initiate.key_size() {
122                    256 | 512 | 1024 => {}
123                    _ => return Err(SrdError::InvalidKeySize),
124                }
125            }
126
127            SrdMessage::Offer(hdr, _offer) => {
128                // No MAC in that message
129                hdr.validate_flags(false)?;
130            }
131
132            SrdMessage::Accept(hdr, _accept) => {
133                // MAC has to be set
134                hdr.validate_flags(true)?;
135            }
136
137            SrdMessage::Confirm(hdr, _confirm) => {
138                // MAC has to be set
139                hdr.validate_flags(true)?;
140            }
141
142            SrdMessage::Delegate(hdr, _delegate) => {
143                // MAC has to be set
144                hdr.validate_flags(true)?;
145            }
146        }
147        Ok(self)
148    }
149}
150
151impl Message for SrdMessage {
152    fn read_from<R: Read>(mut reader: &mut R) -> Result<Self>
153        where
154            Self: Sized,
155    {
156        let header = SrdHeader::read_from(&mut reader)?;
157        match header.msg_type() {
158            srd_msg_id::SRD_INITIATE_MSG_ID => {
159                let initiate = SrdInitiate::read_from(&mut reader)?;
160                Ok(SrdMessage::Initiate(header, initiate).validate()?)
161            }
162            srd_msg_id::SRD_OFFER_MSG_ID => {
163                let offer = SrdOffer::read_from(&mut reader)?;
164                Ok(SrdMessage::Offer(header, offer).validate()?)
165            }
166            srd_msg_id::SRD_ACCEPT_MSG_ID => {
167                let accept = SrdAccept::read_from(&mut reader)?;
168                Ok(SrdMessage::Accept(header, accept).validate()?)
169            }
170            srd_msg_id::SRD_CONFIRM_MSG_ID => {
171                let confirm = SrdConfirm::read_from(&mut reader)?;
172                Ok(SrdMessage::Confirm(header, confirm).validate()?)
173            }
174            srd_msg_id::SRD_DELEGATE_MSG_ID => {
175                let delegate = SrdDelegate::read_from(&mut reader)?;
176                Ok(SrdMessage::Delegate(header, delegate).validate()?)
177            }
178            _ => Err(SrdError::UnknownMsgType),
179        }
180    }
181
182    fn write_to<W: Write>(&self, mut writer: &mut W) -> Result<()> {
183        match self {
184            SrdMessage::Initiate(hdr, initiate) => {
185                hdr.write_to(&mut writer)?;
186                initiate.write_to(&mut writer)?;
187                Ok(())
188            }
189            SrdMessage::Offer(hdr, offer) => {
190                hdr.write_to(&mut writer)?;
191                offer.write_to(&mut writer)?;
192                Ok(())
193            }
194            SrdMessage::Accept(hdr, accept) => {
195                hdr.write_to(&mut writer)?;
196                accept.write_to(&mut writer)?;
197                Ok(())
198            }
199            SrdMessage::Confirm(hdr, confirm) => {
200                hdr.write_to(&mut writer)?;
201                confirm.write_to(&mut writer)?;
202                Ok(())
203            }
204            SrdMessage::Delegate(hdr, delegate) => {
205                hdr.write_to(&mut writer)?;
206                delegate.write_to(&mut writer)?;
207                Ok(())
208            }
209        }
210    }
211}
212
213pub trait ReadMac {
214    fn read_mac(&mut self, mac: &mut [u8]) -> Result<()>;
215}
216
217impl<T: Read> ReadMac for T {
218    fn read_mac(&mut self, mac: &mut [u8]) -> Result<()> {
219        let mut v = Vec::new();
220        self.read_to_end(&mut v)?;
221
222        if v.len() >= mac.len() {
223            let len_to_remove = v.len() - mac.len();
224            mac.copy_from_slice(&v.split_off(len_to_remove));
225            Ok(())
226        } else {
227            Err(SrdError::InvalidDataLength)
228        }
229    }
230}