ecaps2.rs

  1extern crate minidom;
  2
  3use minidom::Element;
  4
  5use error::Error;
  6
  7use disco::{Feature, Identity, Disco, parse_disco};
  8use data_forms::DataForm;
  9
 10fn compute_item(field: &String) -> Vec<u8> {
 11    let mut bytes = field.as_bytes().to_vec();
 12    bytes.push(0x1f);
 13    bytes
 14}
 15
 16fn compute_items<T, F: Fn(&T) -> Vec<u8>>(things: &Vec<T>, separator: u8, encode: F) -> Vec<u8> {
 17    let mut string: Vec<u8> = vec!();
 18    let mut accumulator: Vec<Vec<u8>> = vec!();
 19    for thing in things {
 20        let bytes = encode(thing);
 21        accumulator.push(bytes);
 22    }
 23    // This works using the expected i;octet collation.
 24    accumulator.sort();
 25    for mut bytes in accumulator {
 26        string.append(&mut bytes);
 27    }
 28    string.push(separator);
 29    string
 30}
 31
 32fn compute_features(features: &Vec<Feature>) -> Vec<u8> {
 33    compute_items(features, 0x1c, |feature| compute_item(&feature.var))
 34}
 35
 36fn compute_identities(identities: &Vec<Identity>) -> Vec<u8> {
 37    compute_items(identities, 0x1c, |identity| {
 38        let mut bytes = compute_item(&identity.category);
 39        bytes.append(&mut compute_item(&identity.type_));
 40        bytes.append(&mut compute_item(&identity.xml_lang));
 41        bytes.append(&mut compute_item(&identity.name.clone().unwrap_or(String::new())));
 42        bytes.push(0x1e);
 43        bytes
 44    })
 45}
 46
 47fn compute_extensions(extensions: &Vec<DataForm>) -> Vec<u8> {
 48    compute_items(extensions, 0x1c, |extension| {
 49        compute_items(&extension.fields, 0x1d, |field| {
 50            let mut bytes = compute_item(&field.var);
 51            bytes.append(&mut compute_items(&field.values, 0x1e,
 52                                            |value| compute_item(value)));
 53            bytes
 54        })
 55    })
 56}
 57
 58pub fn compute_disco(disco: &Disco) -> Vec<u8> {
 59    let features_string = compute_features(&disco.features);
 60    let identities_string = compute_identities(&disco.identities);
 61    let extensions_string = compute_extensions(&disco.extensions);
 62
 63    let mut final_string = vec!();
 64    final_string.extend(features_string);
 65    final_string.extend(identities_string);
 66    final_string.extend(extensions_string);
 67    final_string
 68}
 69
 70pub fn convert_element(root: &Element) -> Result<Vec<u8>, Error> {
 71    let disco = parse_disco(root)?;
 72    let final_string = compute_disco(&disco);
 73    Ok(final_string)
 74}
 75
 76#[cfg(test)]
 77mod tests {
 78    use minidom::Element;
 79    use ecaps2;
 80
 81    #[test]
 82    fn test_simple() {
 83        let elem: Element = "<query xmlns='http://jabber.org/protocol/disco#info'><identity category='client' type='pc'/><feature var='http://jabber.org/protocol/disco#info'/></query>".parse().unwrap();
 84        let ecaps2 = ecaps2::convert_element(&elem).unwrap();
 85        assert_eq!(ecaps2.len(), 54);
 86    }
 87
 88    #[test]
 89    fn test_xep_ex1() {
 90        let elem: Element = r#"
 91<query xmlns="http://jabber.org/protocol/disco#info">
 92  <identity category="client" name="BombusMod" type="mobile"/>
 93  <feature var="http://jabber.org/protocol/si"/>
 94  <feature var="http://jabber.org/protocol/bytestreams"/>
 95  <feature var="http://jabber.org/protocol/chatstates"/>
 96  <feature var="http://jabber.org/protocol/disco#info"/>
 97  <feature var="http://jabber.org/protocol/disco#items"/>
 98  <feature var="urn:xmpp:ping"/>
 99  <feature var="jabber:iq:time"/>
100  <feature var="jabber:iq:privacy"/>
101  <feature var="jabber:iq:version"/>
102  <feature var="http://jabber.org/protocol/rosterx"/>
103  <feature var="urn:xmpp:time"/>
104  <feature var="jabber:x:oob"/>
105  <feature var="http://jabber.org/protocol/ibb"/>
106  <feature var="http://jabber.org/protocol/si/profile/file-transfer"/>
107  <feature var="urn:xmpp:receipts"/>
108  <feature var="jabber:iq:roster"/>
109  <feature var="jabber:iq:last"/>
110</query>
111"#.parse().unwrap();
112        let expected = vec![104, 116, 116, 112, 58, 47, 47, 106, 97, 98, 98,
113            101, 114, 46, 111, 114, 103, 47, 112, 114, 111, 116, 111, 99, 111,
114            108, 47, 98, 121, 116, 101, 115, 116, 114, 101, 97, 109, 115, 31,
115            104, 116, 116, 112, 58, 47, 47, 106, 97, 98, 98, 101, 114, 46, 111,
116            114, 103, 47, 112, 114, 111, 116, 111, 99, 111, 108, 47, 99, 104,
117            97, 116, 115, 116, 97, 116, 101, 115, 31, 104, 116, 116, 112, 58,
118            47, 47, 106, 97, 98, 98, 101, 114, 46, 111, 114, 103, 47, 112, 114,
119            111, 116, 111, 99, 111, 108, 47, 100, 105, 115, 99, 111, 35, 105,
120            110, 102, 111, 31, 104, 116, 116, 112, 58, 47, 47, 106, 97, 98, 98,
121            101, 114, 46, 111, 114, 103, 47, 112, 114, 111, 116, 111, 99, 111,
122            108, 47, 100, 105, 115, 99, 111, 35, 105, 116, 101, 109, 115, 31,
123            104, 116, 116, 112, 58, 47, 47, 106, 97, 98, 98, 101, 114, 46, 111,
124            114, 103, 47, 112, 114, 111, 116, 111, 99, 111, 108, 47, 105, 98,
125            98, 31, 104, 116, 116, 112, 58, 47, 47, 106, 97, 98, 98, 101, 114,
126            46, 111, 114, 103, 47, 112, 114, 111, 116, 111, 99, 111, 108, 47,
127            114, 111, 115, 116, 101, 114, 120, 31, 104, 116, 116, 112, 58, 47,
128            47, 106, 97, 98, 98, 101, 114, 46, 111, 114, 103, 47, 112, 114,
129            111, 116, 111, 99, 111, 108, 47, 115, 105, 31, 104, 116, 116, 112,
130            58, 47, 47, 106, 97, 98, 98, 101, 114, 46, 111, 114, 103, 47, 112,
131            114, 111, 116, 111, 99, 111, 108, 47, 115, 105, 47, 112, 114, 111,
132            102, 105, 108, 101, 47, 102, 105, 108, 101, 45, 116, 114, 97, 110,
133            115, 102, 101, 114, 31, 106, 97, 98, 98, 101, 114, 58, 105, 113,
134            58, 108, 97, 115, 116, 31, 106, 97, 98, 98, 101, 114, 58, 105, 113,
135            58, 112, 114, 105, 118, 97, 99, 121, 31, 106, 97, 98, 98, 101, 114,
136            58, 105, 113, 58, 114, 111, 115, 116, 101, 114, 31, 106, 97, 98,
137            98, 101, 114, 58, 105, 113, 58, 116, 105, 109, 101, 31, 106, 97,
138            98, 98, 101, 114, 58, 105, 113, 58, 118, 101, 114, 115, 105, 111,
139            110, 31, 106, 97, 98, 98, 101, 114, 58, 120, 58, 111, 111, 98, 31,
140            117, 114, 110, 58, 120, 109, 112, 112, 58, 112, 105, 110, 103, 31,
141            117, 114, 110, 58, 120, 109, 112, 112, 58, 114, 101, 99, 101, 105,
142            112, 116, 115, 31, 117, 114, 110, 58, 120, 109, 112, 112, 58, 116,
143            105, 109, 101, 31, 28, 99, 108, 105, 101, 110, 116, 31, 109, 111,
144            98, 105, 108, 101, 31, 31, 66, 111, 109, 98, 117, 115, 77, 111,
145            100, 31, 30, 28, 28];
146        let ecaps2 = ecaps2::convert_element(&elem).unwrap();
147        assert_eq!(ecaps2.len(), 0x1d9);
148        assert_eq!(ecaps2, expected);
149
150        /*
151        let sha_256 = hash(ecaps2, "sha-256");
152        assert_eq!(sha_256, "kzBZbkqJ3ADrj7v08reD1qcWUwNGHaidNUgD7nHpiw8=");
153        let sha3_256 = hash(ecaps2, "sha3-256");
154        assert_eq!(sha3_256, "79mdYAfU9rEdTOcWDO7UEAt6E56SUzk/g6TnqUeuD9Q=");
155        */
156    }
157
158    #[test]
159    fn test_xep_ex2() {
160        let elem: Element = r#"
161<query xmlns="http://jabber.org/protocol/disco#info">
162  <identity category="client" name="Tkabber" type="pc" xml:lang="en"/>
163  <identity category="client" name="Ткаббер" type="pc" xml:lang="ru"/>
164  <feature var="games:board"/>
165  <feature var="http://jabber.org/protocol/activity"/>
166  <feature var="http://jabber.org/protocol/activity+notify"/>
167  <feature var="http://jabber.org/protocol/bytestreams"/>
168  <feature var="http://jabber.org/protocol/chatstates"/>
169  <feature var="http://jabber.org/protocol/commands"/>
170  <feature var="http://jabber.org/protocol/disco#info"/>
171  <feature var="http://jabber.org/protocol/disco#items"/>
172  <feature var="http://jabber.org/protocol/evil"/>
173  <feature var="http://jabber.org/protocol/feature-neg"/>
174  <feature var="http://jabber.org/protocol/geoloc"/>
175  <feature var="http://jabber.org/protocol/geoloc+notify"/>
176  <feature var="http://jabber.org/protocol/ibb"/>
177  <feature var="http://jabber.org/protocol/iqibb"/>
178  <feature var="http://jabber.org/protocol/mood"/>
179  <feature var="http://jabber.org/protocol/mood+notify"/>
180  <feature var="http://jabber.org/protocol/rosterx"/>
181  <feature var="http://jabber.org/protocol/si"/>
182  <feature var="http://jabber.org/protocol/si/profile/file-transfer"/>
183  <feature var="http://jabber.org/protocol/tune"/>
184  <feature var="http://www.facebook.com/xmpp/messages"/>
185  <feature var="http://www.xmpp.org/extensions/xep-0084.html#ns-metadata+notify"/>
186  <feature var="jabber:iq:avatar"/>
187  <feature var="jabber:iq:browse"/>
188  <feature var="jabber:iq:dtcp"/>
189  <feature var="jabber:iq:filexfer"/>
190  <feature var="jabber:iq:ibb"/>
191  <feature var="jabber:iq:inband"/>
192  <feature var="jabber:iq:jidlink"/>
193  <feature var="jabber:iq:last"/>
194  <feature var="jabber:iq:oob"/>
195  <feature var="jabber:iq:privacy"/>
196  <feature var="jabber:iq:roster"/>
197  <feature var="jabber:iq:time"/>
198  <feature var="jabber:iq:version"/>
199  <feature var="jabber:x:data"/>
200  <feature var="jabber:x:event"/>
201  <feature var="jabber:x:oob"/>
202  <feature var="urn:xmpp:avatar:metadata+notify"/>
203  <feature var="urn:xmpp:ping"/>
204  <feature var="urn:xmpp:receipts"/>
205  <feature var="urn:xmpp:time"/>
206  <x xmlns="jabber:x:data" type="result">
207    <field type="hidden" var="FORM_TYPE">
208      <value>urn:xmpp:dataforms:softwareinfo</value>
209    </field>
210    <field var="software">
211      <value>Tkabber</value>
212    </field>
213    <field var="software_version">
214      <value>0.11.1-svn-20111216-mod (Tcl/Tk 8.6b2)</value>
215    </field>
216    <field var="os">
217      <value>Windows</value>
218    </field>
219    <field var="os_version">
220      <value>XP</value>
221    </field>
222  </x>
223</query>
224"#.parse().unwrap();
225        let expected = vec![103, 97, 109, 101, 115, 58, 98, 111, 97, 114, 100,
226            31, 104, 116, 116, 112, 58, 47, 47, 106, 97, 98, 98, 101, 114, 46,
227            111, 114, 103, 47, 112, 114, 111, 116, 111, 99, 111, 108, 47, 97,
228            99, 116, 105, 118, 105, 116, 121, 31, 104, 116, 116, 112, 58, 47,
229            47, 106, 97, 98, 98, 101, 114, 46, 111, 114, 103, 47, 112, 114,
230            111, 116, 111, 99, 111, 108, 47, 97, 99, 116, 105, 118, 105, 116,
231            121, 43, 110, 111, 116, 105, 102, 121, 31, 104, 116, 116, 112, 58,
232            47, 47, 106, 97, 98, 98, 101, 114, 46, 111, 114, 103, 47, 112, 114,
233            111, 116, 111, 99, 111, 108, 47, 98, 121, 116, 101, 115, 116, 114,
234            101, 97, 109, 115, 31, 104, 116, 116, 112, 58,47, 47, 106, 97, 98,
235            98, 101, 114, 46, 111, 114, 103, 47, 112, 114, 111, 116, 111, 99,
236            111, 108, 47, 99, 104, 97, 116, 115, 116, 97, 116, 101, 115, 31,
237            104, 116, 116, 112, 58, 47, 47, 106, 97, 98, 98, 101, 114, 46, 111,
238            114, 103, 47, 112, 114, 111, 116, 111, 99, 111, 108, 47, 99, 111,
239            109, 109, 97, 110, 100, 115, 31,104,116, 116, 112, 58, 47, 47, 106,
240            97, 98, 98, 101, 114, 46, 111, 114, 103, 47, 112, 114, 111, 116,
241            111, 99, 111, 108, 47, 100, 105, 115, 99, 111, 35, 105, 110, 102,
242            111, 31, 104, 116, 116, 112, 58, 47, 47, 106, 97, 98, 98, 101, 114,
243            46, 111, 114, 103, 47, 112, 114, 111, 116, 111, 99, 111, 108, 47,
244            100, 105, 115, 99, 111, 35, 105, 116, 101, 109, 115, 31, 104, 116,
245            116, 112, 58, 47, 47, 106, 97, 98, 98, 101, 114, 46, 111, 114, 103,
246            47, 112, 114, 111, 116, 111, 99, 111, 108, 47, 101, 118, 105, 108,
247            31, 104, 116, 116, 112, 58, 47, 47, 106, 97, 98, 98, 101, 114, 46,
248            111, 114, 103, 47, 112, 114, 111, 116, 111, 99, 111, 108, 47, 102,
249            101, 97, 116, 117, 114, 101, 45, 110, 101, 103, 31, 104, 116, 116,
250            112, 58, 47, 47, 106, 97, 98, 98, 101, 114, 46, 111, 114, 103, 47,
251            112, 114, 111, 116, 111, 99, 111, 108, 47, 103, 101, 111, 108, 111,
252            99, 31, 104, 116, 116, 112, 58, 47, 47, 106, 97, 98, 98, 101, 114,
253            46, 111, 114, 103, 47, 112, 114, 111, 116, 111, 99,111, 108, 47,
254            103, 101, 111, 108, 111, 99, 43, 110, 111, 116, 105, 102, 121, 31,
255            104, 116, 116, 112, 58, 47, 47, 106, 97, 98, 98, 101, 114, 46, 111,
256            114, 103,47, 112, 114, 111, 116, 111, 99, 111, 108, 47, 105, 98,
257            98, 31, 104, 116, 116, 112, 58, 47, 47, 106, 97, 98, 98, 101, 114,
258            46, 111, 114, 103, 47, 112, 114, 111,116, 111, 99, 111, 108, 47,
259            105, 113, 105, 98, 98, 31, 104, 116, 116, 112, 58, 47, 47, 106, 97,
260            98, 98, 101, 114, 46, 111, 114, 103, 47, 112, 114, 111, 116,111,
261            99, 111, 108, 47, 109, 111, 111, 100, 31, 104, 116, 116, 112, 58,
262            47, 47, 106, 97, 98, 98, 101, 114, 46, 111, 114, 103, 47, 112, 114,
263            111, 116, 111, 99, 111,108, 47, 109, 111, 111, 100, 43, 110, 111,
264            116, 105, 102, 121, 31, 104, 116, 116, 112, 58, 47, 47, 106, 97,
265            98, 98, 101, 114, 46, 111, 114, 103, 47, 112, 114, 111, 116, 111,
266            99, 111, 108, 47, 114, 111, 115, 116, 101, 114, 120, 31, 104, 116,
267            116, 112, 58, 47, 47, 106, 97, 98, 98, 101, 114, 46, 111, 114, 103,
268            47, 112, 114, 111, 116, 111, 99, 111, 108, 47, 115, 105, 31, 104,
269            116, 116, 112, 58, 47, 47, 106, 97, 98, 98, 101, 114, 46, 111, 114,
270            103, 47, 112, 114, 111, 116, 111, 99, 111, 108, 47, 115, 105, 47,
271            112, 114, 111, 102, 105, 108, 101, 47, 102, 105, 108, 101, 45, 116,
272            114, 97, 110, 115, 102, 101, 114, 31, 104, 116, 116, 112, 58, 47,
273            47, 106, 97, 98, 98, 101, 114, 46, 111, 114, 103, 47, 112, 114,
274            111, 116, 111, 99, 111, 108, 47, 116, 117, 110, 101, 31, 104, 116,
275            116, 112, 58, 47, 47, 119, 119, 119, 46, 102, 97, 99, 101, 98, 111,
276            111, 107, 46, 99, 111, 109, 47, 120, 109, 112, 112, 47, 109, 101,
277            115, 115, 97, 103, 101, 115, 31, 104, 116, 116, 112, 58, 47, 47,
278            119, 119, 119, 46, 120, 109, 112, 112, 46, 111, 114, 103, 47, 101,
279            120, 116, 101, 110, 115, 105, 111, 110, 115, 47, 120, 101, 112, 45,
280            48, 48, 56, 52, 46, 104, 116, 109, 108, 35, 110, 115, 45, 109, 101,
281            116, 97, 100, 97, 116, 97, 43, 110, 111, 116, 105, 102, 121, 31,
282            106, 97, 98, 98, 101, 114,58, 105,113, 58, 97, 118, 97, 116, 97,
283            114, 31, 106, 97, 98, 98, 101, 114, 58, 105, 113, 58, 98, 114, 111,
284            119, 115, 101, 31, 106, 97, 98, 98, 101, 114, 58, 105, 113, 58,
285            100, 116, 99, 112, 31, 106, 97, 98, 98, 101, 114, 58, 105, 113, 58,
286            102, 105, 108, 101, 120, 102, 101, 114, 31, 106, 97, 98, 98, 101,
287            114, 58, 105, 113, 58, 105, 98, 98, 31, 106, 97, 98, 98, 101, 114,
288            58, 105, 113, 58, 105, 110, 98, 97, 110, 100, 31, 106, 97, 98, 98,
289            101, 114, 58, 105, 113, 58, 106, 105, 100, 108, 105, 110, 107, 31,
290            106, 97, 98, 98, 101, 114, 58, 105, 113, 58, 108, 97, 115, 116, 31,
291            106, 97, 98, 98, 101, 114, 58, 105, 113, 58, 111, 111, 98, 31, 106,
292            97,98, 98, 101, 114, 58, 105, 113, 58, 112, 114, 105, 118, 97, 99,
293            121, 31, 106, 97, 98, 98, 101, 114, 58, 105, 113, 58, 114, 111,
294            115, 116, 101, 114,31, 106, 97, 98, 98, 101, 114, 58, 105, 113, 58,
295            116, 105, 109, 101, 31, 106, 97, 98, 98, 101, 114, 58, 105, 113,
296            58, 118, 101, 114, 115, 105, 111, 110, 31, 106, 97, 98, 98, 101,
297            114, 58, 120, 58, 100, 97, 116, 97, 31, 106, 97, 98, 98, 101, 114,
298            58, 120, 58, 101, 118, 101, 110, 116, 31, 106, 97, 98, 98, 101,
299            114, 58, 120, 58, 111, 111, 98, 31, 117, 114, 110, 58, 120, 109,
300            112, 112, 58, 97, 118, 97, 116, 97, 114, 58, 109, 101, 116, 97,
301            100, 97, 116, 97, 43, 110, 111, 116, 105, 102, 121,31, 117, 114,
302            110, 58, 120, 109, 112, 112, 58, 112, 105, 110, 103, 31, 117, 114,
303            110, 58, 120, 109, 112, 112, 58, 114, 101, 99, 101, 105, 112, 116,
304            115, 31, 117, 114, 110, 58, 120, 109, 112, 112, 58, 116, 105, 109,
305            101, 31, 28, 99, 108, 105, 101, 110, 116, 31, 112, 99, 31, 101,
306            110, 31, 84, 107, 97, 98, 98, 101, 114,31, 30, 99, 108, 105, 101,
307            110, 116, 31, 112, 99, 31, 114, 117, 31, 208, 162, 208, 186, 208,
308            176, 208, 177, 208, 177, 208, 181, 209, 128, 31, 30, 28, 70, 79,
309            82, 77, 95, 84, 89, 80, 69, 31, 117, 114, 110, 58, 120, 109, 112,
310            112, 58, 100, 97, 116, 97, 102, 111, 114, 109, 115, 58, 115, 111,
311            102, 116, 119, 97, 114, 101,105, 110, 102, 111, 31, 30, 111, 115,
312            31, 87, 105, 110, 100, 111, 119, 115, 31, 30, 111, 115, 95, 118,
313            101, 114, 115, 105, 111, 110, 31, 88, 80, 31, 30, 115, 111, 102,
314            116, 119, 97, 114, 101, 31, 84, 107, 97, 98, 98, 101, 114, 31, 30,
315            115, 111, 102, 116, 119, 97, 114, 101, 95, 118, 101, 114, 115, 105,
316            111, 110, 31, 48, 46, 49, 49, 46, 49, 45, 115, 118, 110, 45, 50,
317            48, 49, 49, 49, 50, 49, 54, 45, 109, 111, 100, 32, 40, 84, 99, 108,
318            47, 84, 107, 32, 56, 46,54, 98, 50, 41, 31, 30, 29, 28];
319        let ecaps2 = ecaps2::convert_element(&elem).unwrap();
320        assert_eq!(ecaps2.len(), 0x543);
321        assert_eq!(ecaps2, expected);
322
323        /*
324        let sha_256 = hash(ecaps2, "sha-256");
325        assert_eq!(sha_256, "u79ZroNJbdSWhdSp311mddz44oHHPsEBntQ5b1jqBSY=");
326        let sha3_256 = hash(ecaps2, "sha3-256");
327        assert_eq!(sha3_256, "XpUJzLAc93258sMECZ3FJpebkzuyNXDzRNwQog8eycg=");
328        */
329    }
330}