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