xref: /webrtc/stun/src/message/message_test.rs (revision d7232c2b)
1 use super::*;
2 use crate::xoraddr::*;
3 
4 use crate::fingerprint::FINGERPRINT;
5 use crate::integrity::MessageIntegrity;
6 use crate::textattrs::TextAttribute;
7 use std::io::{BufReader, BufWriter};
8 
9 #[test]
10 fn test_message_buffer() -> Result<()> {
11     let mut m = Message::new();
12     m.typ = MessageType {
13         method: METHOD_BINDING,
14         class: CLASS_REQUEST,
15     };
16     m.transaction_id = TransactionId::new();
17     m.add(ATTR_ERROR_CODE, &[0xff, 0xfe, 0xfa]);
18     m.write_header();
19 
20     let mut m_decoded = Message::new();
21     let mut reader = BufReader::new(m.raw.as_slice());
22     m_decoded.read_from(&mut reader)?;
23 
24     assert_eq!(m_decoded, m, "{} != {}", m_decoded, m);
25 
26     Ok(())
27 }
28 
29 #[test]
30 fn test_message_type_value() -> Result<()> {
31     let tests = vec![
32         (
33             MessageType {
34                 method: METHOD_BINDING,
35                 class: CLASS_REQUEST,
36             },
37             0x0001,
38         ),
39         (
40             MessageType {
41                 method: METHOD_BINDING,
42                 class: CLASS_SUCCESS_RESPONSE,
43             },
44             0x0101,
45         ),
46         (
47             MessageType {
48                 method: METHOD_BINDING,
49                 class: CLASS_ERROR_RESPONSE,
50             },
51             0x0111,
52         ),
53         (
54             MessageType {
55                 method: Method(0xb6d),
56                 class: MessageClass(0x3),
57             },
58             0x2ddd,
59         ),
60     ];
61 
62     for (input, output) in tests {
63         let b = input.value();
64         assert_eq!(b, output, "Value({}) -> {}, want {}", input, b, output);
65     }
66 
67     Ok(())
68 }
69 
70 #[test]
71 fn test_message_type_read_value() -> Result<()> {
72     let tests = vec![
73         (
74             0x0001,
75             MessageType {
76                 method: METHOD_BINDING,
77                 class: CLASS_REQUEST,
78             },
79         ),
80         (
81             0x0101,
82             MessageType {
83                 method: METHOD_BINDING,
84                 class: CLASS_SUCCESS_RESPONSE,
85             },
86         ),
87         (
88             0x0111,
89             MessageType {
90                 method: METHOD_BINDING,
91                 class: CLASS_ERROR_RESPONSE,
92             },
93         ),
94     ];
95 
96     for (input, output) in tests {
97         let mut m = MessageType::default();
98         m.read_value(input);
99         assert_eq!(m, output, "ReadValue({}) -> {}, want {}", input, m, output);
100     }
101 
102     Ok(())
103 }
104 
105 #[test]
106 fn test_message_type_read_write_value() -> Result<()> {
107     let tests = vec![
108         MessageType {
109             method: METHOD_BINDING,
110             class: CLASS_REQUEST,
111         },
112         MessageType {
113             method: METHOD_BINDING,
114             class: CLASS_SUCCESS_RESPONSE,
115         },
116         MessageType {
117             method: METHOD_BINDING,
118             class: CLASS_ERROR_RESPONSE,
119         },
120         MessageType {
121             method: Method(0x12),
122             class: CLASS_ERROR_RESPONSE,
123         },
124     ];
125 
126     for test in tests {
127         let mut m = MessageType::default();
128         let v = test.value();
129         m.read_value(v);
130         assert_eq!(
131             m, test,
132             "ReadValue({} -> {}) = {}, should be {}",
133             test, v, m, test
134         );
135     }
136 
137     Ok(())
138 }
139 
140 #[test]
141 fn test_message_write_to() -> Result<()> {
142     let mut m = Message::new();
143     m.typ = MessageType {
144         method: METHOD_BINDING,
145         class: CLASS_REQUEST,
146     };
147     m.transaction_id = TransactionId::new();
148     m.add(ATTR_ERROR_CODE, &[0xff, 0xfe, 0xfa]);
149     m.write_header();
150     let mut buf = vec![];
151     {
152         let mut writer = BufWriter::<&mut Vec<u8>>::new(buf.as_mut());
153         m.write_to(&mut writer)?;
154     }
155 
156     let mut m_decoded = Message::new();
157     let mut reader = BufReader::new(buf.as_slice());
158     m_decoded.read_from(&mut reader)?;
159     assert_eq!(m_decoded, m, "{} != {}", m_decoded, m);
160 
161     Ok(())
162 }
163 
164 #[test]
165 fn test_message_cookie() -> Result<()> {
166     let buf = vec![0; 20];
167     let mut m_decoded = Message::new();
168     let mut reader = BufReader::new(buf.as_slice());
169     let result = m_decoded.read_from(&mut reader);
170     assert!(result.is_err(), "should error");
171 
172     Ok(())
173 }
174 
175 #[test]
176 fn test_message_length_less_header_size() -> Result<()> {
177     let buf = vec![0; 8];
178     let mut m_decoded = Message::new();
179     let mut reader = BufReader::new(buf.as_slice());
180     let result = m_decoded.read_from(&mut reader);
181     assert!(result.is_err(), "should error");
182 
183     Ok(())
184 }
185 
186 #[test]
187 fn test_message_bad_length() -> Result<()> {
188     let m_type = MessageType {
189         method: METHOD_BINDING,
190         class: CLASS_REQUEST,
191     };
192     let mut m = Message {
193         typ: m_type,
194         length: 4,
195         transaction_id: TransactionId([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]),
196         ..Default::default()
197     };
198     m.add(AttrType(0x1), &[1, 2]);
199     m.write_header();
200     m.raw[20 + 3] = 10; // set attr length = 10
201 
202     let mut m_decoded = Message::new();
203     let result = m_decoded.write(&m.raw);
204     assert!(result.is_err(), "should error");
205 
206     Ok(())
207 }
208 
209 #[test]
210 fn test_message_attr_length_less_than_header() -> Result<()> {
211     let m_type = MessageType {
212         method: METHOD_BINDING,
213         class: CLASS_REQUEST,
214     };
215     let message_attribute = RawAttribute {
216         length: 2,
217         value: vec![1, 2],
218         typ: AttrType(0x1),
219     };
220     let message_attributes = Attributes(vec![message_attribute]);
221     let mut m = Message {
222         typ: m_type,
223         transaction_id: TransactionId::new(),
224         attributes: message_attributes,
225         ..Default::default()
226     };
227     m.encode();
228 
229     let mut m_decoded = Message::new();
230     m.raw[3] = 2; // rewrite to bad length
231 
232     let mut reader = BufReader::new(&m.raw[..20 + 2]);
233     let result = m_decoded.read_from(&mut reader);
234     assert!(result.is_err(), "should be error");
235 
236     Ok(())
237 }
238 
239 #[test]
240 fn test_message_attr_size_less_than_length() -> Result<()> {
241     let m_type = MessageType {
242         method: METHOD_BINDING,
243         class: CLASS_REQUEST,
244     };
245     let message_attribute = RawAttribute {
246         length: 4,
247         value: vec![1, 2, 3, 4],
248         typ: AttrType(0x1),
249     };
250     let message_attributes = Attributes(vec![message_attribute]);
251     let mut m = Message {
252         typ: m_type,
253         transaction_id: TransactionId::new(),
254         attributes: message_attributes,
255         ..Default::default()
256     };
257     m.write_attributes();
258     m.write_header();
259     m.raw[3] = 5; // rewrite to bad length
260 
261     let mut m_decoded = Message::new();
262     let mut reader = BufReader::new(&m.raw[..20 + 5]);
263     let result = m_decoded.read_from(&mut reader);
264     assert!(result.is_err(), "should be error");
265 
266     Ok(())
267 }
268 
269 #[test]
270 fn test_message_read_from_error() -> Result<()> {
271     let mut m_decoded = Message::new();
272     let buf = vec![];
273     let mut reader = BufReader::new(buf.as_slice());
274     let result = m_decoded.read_from(&mut reader);
275     assert!(result.is_err(), "should be error");
276 
277     Ok(())
278 }
279 
280 #[test]
281 fn test_message_class_string() -> Result<()> {
282     let v = vec![
283         CLASS_REQUEST,
284         CLASS_ERROR_RESPONSE,
285         CLASS_SUCCESS_RESPONSE,
286         CLASS_INDICATION,
287     ];
288 
289     for k in v {
290         if k.to_string() == *"unknown message class" {
291             panic!("bad stringer {}", k);
292         }
293     }
294 
295     // should panic
296     let p = MessageClass(0x05).to_string();
297     assert_eq!(p, "unknown message class", "should be error {}", p);
298 
299     Ok(())
300 }
301 
302 #[test]
303 fn test_attr_type_string() -> Result<()> {
304     let v = vec![
305         ATTR_MAPPED_ADDRESS,
306         ATTR_USERNAME,
307         ATTR_ERROR_CODE,
308         ATTR_MESSAGE_INTEGRITY,
309         ATTR_UNKNOWN_ATTRIBUTES,
310         ATTR_REALM,
311         ATTR_NONCE,
312         ATTR_XORMAPPED_ADDRESS,
313         ATTR_SOFTWARE,
314         ATTR_ALTERNATE_SERVER,
315         ATTR_FINGERPRINT,
316     ];
317     for k in v {
318         assert!(!k.to_string().starts_with("0x"), "bad stringer");
319     }
320 
321     let v_non_standard = AttrType(0x512);
322     assert!(
323         v_non_standard.to_string().starts_with("0x512"),
324         "bad prefix"
325     );
326 
327     Ok(())
328 }
329 
330 #[test]
331 fn test_method_string() -> Result<()> {
332     assert_eq!(
333         METHOD_BINDING.to_string(),
334         "Binding".to_owned(),
335         "binding is not binding!"
336     );
337     assert_eq!(
338         Method(0x616).to_string(),
339         "0x616".to_owned(),
340         "Bad stringer {}",
341         Method(0x616)
342     );
343 
344     Ok(())
345 }
346 
347 #[test]
348 fn test_attribute_equal() -> Result<()> {
349     let a = RawAttribute {
350         length: 2,
351         value: vec![0x1, 0x2],
352         ..Default::default()
353     };
354     let b = RawAttribute {
355         length: 2,
356         value: vec![0x1, 0x2],
357         ..Default::default()
358     };
359     assert_eq!(a, b, "should equal");
360 
361     assert_ne!(
362         a,
363         RawAttribute {
364             typ: AttrType(0x2),
365             ..Default::default()
366         },
367         "should not equal"
368     );
369     assert_ne!(
370         a,
371         RawAttribute {
372             length: 0x2,
373             ..Default::default()
374         },
375         "should not equal"
376     );
377     assert_ne!(
378         a,
379         RawAttribute {
380             length: 0x3,
381             ..Default::default()
382         },
383         "should not equal"
384     );
385     assert_ne!(
386         a,
387         RawAttribute {
388             length: 0x2,
389             value: vec![0x1, 0x3],
390             ..Default::default()
391         },
392         "should not equal"
393     );
394 
395     Ok(())
396 }
397 
398 #[test]
399 fn test_message_equal() -> Result<()> {
400     let attr = RawAttribute {
401         length: 2,
402         value: vec![0x1, 0x2],
403         typ: AttrType(0x1),
404     };
405     let attrs = Attributes(vec![attr]);
406     let a = Message {
407         attributes: attrs.clone(),
408         length: 4 + 2,
409         ..Default::default()
410     };
411     let b = Message {
412         attributes: attrs.clone(),
413         length: 4 + 2,
414         ..Default::default()
415     };
416     assert_eq!(a, b, "should equal");
417     assert_ne!(
418         a,
419         Message {
420             typ: MessageType {
421                 class: MessageClass(128),
422                 ..Default::default()
423             },
424             ..Default::default()
425         },
426         "should not equal"
427     );
428 
429     let t_id = TransactionId([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
430 
431     assert_ne!(
432         a,
433         Message {
434             transaction_id: t_id,
435             ..Default::default()
436         },
437         "should not equal"
438     );
439     assert_ne!(
440         a,
441         Message {
442             length: 3,
443             ..Default::default()
444         },
445         "should not equal"
446     );
447 
448     let t_attrs = Attributes(vec![RawAttribute {
449         length: 1,
450         value: vec![0x1],
451         typ: AttrType(0x1),
452     }]);
453     assert_ne!(
454         a,
455         Message {
456             attributes: t_attrs,
457             length: 4 + 2,
458             ..Default::default()
459         },
460         "should not equal"
461     );
462 
463     let t_attrs = Attributes(vec![RawAttribute {
464         length: 2,
465         value: vec![0x1, 0x1],
466         typ: AttrType(0x2),
467     }]);
468     assert_ne!(
469         a,
470         Message {
471             attributes: t_attrs,
472             length: 4 + 2,
473             ..Default::default()
474         },
475         "should not equal"
476     );
477 
478     //"Nil attributes"
479     {
480         let a = Message {
481             length: 4 + 2,
482             ..Default::default()
483         };
484         let mut b = Message {
485             attributes: attrs,
486             length: 4 + 2,
487             ..Default::default()
488         };
489 
490         assert_ne!(a, b, "should not equal");
491         assert_ne!(b, a, "should not equal");
492         b.attributes = Attributes::default();
493         assert_eq!(a, b, "should equal");
494     }
495 
496     //"Attributes length"
497     {
498         let attr = RawAttribute {
499             length: 2,
500             value: vec![0x1, 0x2],
501             typ: AttrType(0x1),
502         };
503         let attr1 = RawAttribute {
504             length: 2,
505             value: vec![0x1, 0x2],
506             typ: AttrType(0x1),
507         };
508         let a = Message {
509             attributes: Attributes(vec![attr.clone()]),
510             length: 4 + 2,
511             ..Default::default()
512         };
513         let b = Message {
514             attributes: Attributes(vec![attr, attr1]),
515             length: 4 + 2,
516             ..Default::default()
517         };
518         assert_ne!(a, b, "should not equal");
519     }
520 
521     //"Attributes values"
522     {
523         let attr = RawAttribute {
524             length: 2,
525             value: vec![0x1, 0x2],
526             typ: AttrType(0x1),
527         };
528         let attr1 = RawAttribute {
529             length: 2,
530             value: vec![0x1, 0x1],
531             typ: AttrType(0x1),
532         };
533         let a = Message {
534             attributes: Attributes(vec![attr.clone(), attr.clone()]),
535             length: 4 + 2,
536             ..Default::default()
537         };
538         let b = Message {
539             attributes: Attributes(vec![attr, attr1]),
540             length: 4 + 2,
541             ..Default::default()
542         };
543         assert_ne!(a, b, "should not equal");
544     }
545 
546     Ok(())
547 }
548 
549 #[test]
550 fn test_message_grow() -> Result<()> {
551     let mut m = Message::new();
552     m.grow(512, false);
553     assert_eq!(m.raw.len(), 512, "Bad length {}", m.raw.len());
554 
555     Ok(())
556 }
557 
558 #[test]
559 fn test_message_grow_smaller() -> Result<()> {
560     let mut m = Message::new();
561     m.grow(2, false);
562     assert!(m.raw.capacity() >= 20, "Bad capacity {}", m.raw.capacity());
563 
564     assert!(m.raw.len() >= 20, "Bad length {}", m.raw.len());
565 
566     Ok(())
567 }
568 
569 #[test]
570 fn test_message_string() -> Result<()> {
571     let m = Message::new();
572     assert_ne!(m.to_string(), "", "bad string");
573 
574     Ok(())
575 }
576 
577 #[test]
578 fn test_is_message() -> Result<()> {
579     let mut m = Message::new();
580     let a = TextAttribute {
581         attr: ATTR_SOFTWARE,
582         text: "software".to_owned(),
583     };
584     a.add_to(&mut m)?;
585     m.write_header();
586 
587     let tests = vec![
588         (vec![], false),                           // 0
589         (vec![1, 2, 3], false),                    // 1
590         (vec![1, 2, 4], false),                    // 2
591         (vec![1, 2, 4, 5, 6, 7, 8, 9, 20], false), // 3
592         (m.raw.to_vec(), true),                    // 5
593         (
594             vec![
595                 0, 0, 0, 0, 33, 18, 164, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
596             ],
597             true,
598         ), // 6
599     ];
600 
601     for (input, output) in tests {
602         let got = is_message(&input);
603         assert_eq!(got, output, "IsMessage({:?}) {} != {}", input, got, output);
604     }
605 
606     Ok(())
607 }
608 
609 #[test]
610 fn test_message_contains() -> Result<()> {
611     let mut m = Message::new();
612     m.add(ATTR_SOFTWARE, "value".as_bytes());
613 
614     assert!(m.contains(ATTR_SOFTWARE), "message should contain software");
615     assert!(!m.contains(ATTR_NONCE), "message should not contain nonce");
616 
617     Ok(())
618 }
619 
620 #[test]
621 fn test_message_full_size() -> Result<()> {
622     let mut m = Message::new();
623     m.build(&[
624         Box::new(BINDING_REQUEST),
625         Box::new(TransactionId([1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 0])),
626         Box::new(TextAttribute::new(ATTR_SOFTWARE, "pion/stun".to_owned())),
627         Box::new(MessageIntegrity::new_long_term_integrity(
628             "username".to_owned(),
629             "realm".to_owned(),
630             "password".to_owned(),
631         )),
632         Box::new(FINGERPRINT),
633     ])?;
634     let l = m.raw.len();
635     m.raw = m.raw[..l - 10].to_vec();
636 
637     let mut decoder = Message::new();
638     let l = m.raw.len();
639     decoder.raw = m.raw[..l - 10].to_vec();
640     let result = decoder.decode();
641     assert!(result.is_err(), "decode on truncated buffer should error");
642 
643     Ok(())
644 }
645 
646 #[test]
647 fn test_message_clone_to() -> Result<()> {
648     let mut m = Message::new();
649     m.build(&[
650         Box::new(BINDING_REQUEST),
651         Box::new(TransactionId([1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 0])),
652         Box::new(TextAttribute::new(ATTR_SOFTWARE, "pion/stun".to_owned())),
653         Box::new(MessageIntegrity::new_long_term_integrity(
654             "username".to_owned(),
655             "realm".to_owned(),
656             "password".to_owned(),
657         )),
658         Box::new(FINGERPRINT),
659     ])?;
660     m.encode();
661 
662     let mut b = Message::new();
663     m.clone_to(&mut b)?;
664     assert_eq!(b, m, "not equal");
665 
666     //TODO: Corrupting m and checking that b is not corrupted.
667     /*let (mut s, ok) = b.attributes.get(ATTR_SOFTWARE);
668     assert!(ok, "no software attribute");
669     s.value[0] = b'k';
670     s.add_to(&mut b)?;
671     assert_ne!(b, m, "should not be equal");*/
672 
673     Ok(())
674 }
675 
676 #[test]
677 fn test_message_add_to() -> Result<()> {
678     let mut m = Message::new();
679     m.build(&[
680         Box::new(BINDING_REQUEST),
681         Box::new(TransactionId([1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 0])),
682         Box::new(FINGERPRINT),
683     ])?;
684     m.encode();
685 
686     let mut b = Message::new();
687     m.clone_to(&mut b)?;
688 
689     m.transaction_id = TransactionId([1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 2, 0]);
690     assert_ne!(b, m, "should not be equal");
691 
692     m.add_to(&mut b)?;
693     assert_eq!(b, m, "should be equal");
694 
695     Ok(())
696 }
697 
698 #[test]
699 fn test_decode() -> Result<()> {
700     let mut m = Message::new();
701     m.typ = MessageType {
702         method: METHOD_BINDING,
703         class: CLASS_REQUEST,
704     };
705     m.transaction_id = TransactionId::new();
706     m.add(ATTR_ERROR_CODE, &[0xff, 0xfe, 0xfa]);
707     m.write_header();
708 
709     let mut m_decoded = Message::new();
710     m_decoded.raw.clear();
711     m_decoded.raw.extend_from_slice(&m.raw);
712     m_decoded.decode()?;
713     assert_eq!(
714         m_decoded, m,
715         "decoded result is not equal to encoded message"
716     );
717 
718     Ok(())
719 }
720 
721 #[test]
722 fn test_message_marshal_binary() -> Result<()> {
723     let mut m = Message::new();
724     m.build(&[
725         Box::new(TextAttribute::new(ATTR_SOFTWARE, "software".to_owned())),
726         Box::new(XorMappedAddress {
727             ip: "213.1.223.5".parse().unwrap(),
728             port: 0,
729         }),
730     ])?;
731 
732     let mut data = m.marshal_binary()?;
733     // Reset m.Raw to check retention.
734     for i in 0..m.raw.len() {
735         m.raw[i] = 0;
736     }
737     m.unmarshal_binary(&data)?;
738 
739     // Reset data to check retention.
740     #[allow(clippy::needless_range_loop)]
741     for i in 0..data.len() {
742         data[i] = 0;
743     }
744 
745     m.decode()?;
746 
747     Ok(())
748 }
749