1 /* 2 * libjingle 3 * Copyright 2004 Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include <string> 29 30 #include "talk/base/bytebuffer.h" 31 #include "talk/base/gunit.h" 32 #include "talk/base/logging.h" 33 #include "talk/base/messagedigest.h" 34 #include "talk/base/scoped_ptr.h" 35 #include "talk/base/socketaddress.h" 36 #include "talk/p2p/base/stun.h" 37 38 namespace cricket { 39 40 class StunTest : public ::testing::Test { 41 protected: 42 void CheckStunHeader(const StunMessage& msg, StunMessageType expected_type, 43 size_t expected_length) { 44 ASSERT_EQ(expected_type, msg.type()); 45 ASSERT_EQ(expected_length, msg.length()); 46 } 47 48 void CheckStunTransactionID(const StunMessage& msg, 49 const unsigned char* expectedID, size_t length) { 50 ASSERT_EQ(length, msg.transaction_id().size()); 51 ASSERT_EQ(length == kStunTransactionIdLength + 4, msg.IsLegacy()); 52 ASSERT_EQ(length == kStunTransactionIdLength, !msg.IsLegacy()); 53 ASSERT_EQ(0, memcmp(msg.transaction_id().c_str(), expectedID, length)); 54 } 55 56 void CheckStunAddressAttribute(const StunAddressAttribute* addr, 57 StunAddressFamily expected_family, 58 int expected_port, 59 talk_base::IPAddress expected_address) { 60 ASSERT_EQ(expected_family, addr->family()); 61 ASSERT_EQ(expected_port, addr->port()); 62 63 if (addr->family() == STUN_ADDRESS_IPV4) { 64 in_addr v4_address = expected_address.ipv4_address(); 65 in_addr stun_address = addr->ipaddr().ipv4_address(); 66 ASSERT_EQ(0, memcmp(&v4_address, &stun_address, sizeof(stun_address))); 67 } else if (addr->family() == STUN_ADDRESS_IPV6) { 68 in6_addr v6_address = expected_address.ipv6_address(); 69 in6_addr stun_address = addr->ipaddr().ipv6_address(); 70 ASSERT_EQ(0, memcmp(&v6_address, &stun_address, sizeof(stun_address))); 71 } else { 72 ASSERT_TRUE(addr->family() == STUN_ADDRESS_IPV6 || 73 addr->family() == STUN_ADDRESS_IPV4); 74 } 75 } 76 77 size_t ReadStunMessageTestCase(StunMessage* msg, 78 const unsigned char* testcase, 79 size_t size) { 80 const char* input = reinterpret_cast<const char*>(testcase); 81 talk_base::ByteBuffer buf(input, size); 82 if (msg->Read(&buf)) { 83 // Returns the size the stun message should report itself as being 84 return (size - 20); 85 } else { 86 return 0; 87 } 88 } 89 }; 90 91 92 // Sample STUN packets with various attributes 93 // Gathered by wiresharking pjproject's pjnath test programs 94 // pjproject available at www.pjsip.org 95 96 static const unsigned char kStunMessageWithIPv6MappedAddress[] = { 97 0x00, 0x01, 0x00, 0x18, // message header 98 0x21, 0x12, 0xa4, 0x42, // transaction id 99 0x29, 0x1f, 0xcd, 0x7c, 100 0xba, 0x58, 0xab, 0xd7, 101 0xf2, 0x41, 0x01, 0x00, 102 0x00, 0x01, 0x00, 0x14, // Address type (mapped), length 103 0x00, 0x02, 0xb8, 0x81, // family (IPv6), port 104 0x24, 0x01, 0xfa, 0x00, // an IPv6 address 105 0x00, 0x04, 0x10, 0x00, 106 0xbe, 0x30, 0x5b, 0xff, 107 0xfe, 0xe5, 0x00, 0xc3 108 }; 109 110 static const unsigned char kStunMessageWithIPv4MappedAddress[] = { 111 0x01, 0x01, 0x00, 0x0c, // binding response, length 12 112 0x21, 0x12, 0xa4, 0x42, // magic cookie 113 0x29, 0x1f, 0xcd, 0x7c, // transaction ID 114 0xba, 0x58, 0xab, 0xd7, 115 0xf2, 0x41, 0x01, 0x00, 116 0x00, 0x01, 0x00, 0x08, // Mapped, 8 byte length 117 0x00, 0x01, 0x9d, 0xfc, // AF_INET, unxor-ed port 118 0xac, 0x17, 0x44, 0xe6 // IPv4 address 119 }; 120 121 // Test XOR-mapped IP addresses: 122 static const unsigned char kStunMessageWithIPv6XorMappedAddress[] = { 123 0x01, 0x01, 0x00, 0x18, // message header (binding response) 124 0x21, 0x12, 0xa4, 0x42, // magic cookie (rfc5389) 125 0xe3, 0xa9, 0x46, 0xe1, // transaction ID 126 0x7c, 0x00, 0xc2, 0x62, 127 0x54, 0x08, 0x01, 0x00, 128 0x00, 0x20, 0x00, 0x14, // Address Type (XOR), length 129 0x00, 0x02, 0xcb, 0x5b, // family, XOR-ed port 130 0x05, 0x13, 0x5e, 0x42, // XOR-ed IPv6 address 131 0xe3, 0xad, 0x56, 0xe1, 132 0xc2, 0x30, 0x99, 0x9d, 133 0xaa, 0xed, 0x01, 0xc3 134 }; 135 136 static const unsigned char kStunMessageWithIPv4XorMappedAddress[] = { 137 0x01, 0x01, 0x00, 0x0c, // message header (binding response) 138 0x21, 0x12, 0xa4, 0x42, // magic cookie 139 0x29, 0x1f, 0xcd, 0x7c, // transaction ID 140 0xba, 0x58, 0xab, 0xd7, 141 0xf2, 0x41, 0x01, 0x00, 142 0x00, 0x20, 0x00, 0x08, // address type (xor), length 143 0x00, 0x01, 0xfc, 0xb5, // family (AF_INET), XOR-ed port 144 0x8d, 0x05, 0xe0, 0xa4 // IPv4 address 145 }; 146 147 // ByteString Attribute (username) 148 static const unsigned char kStunMessageWithByteStringAttribute[] = { 149 0x00, 0x01, 0x00, 0x0c, 150 0x21, 0x12, 0xa4, 0x42, 151 0xe3, 0xa9, 0x46, 0xe1, 152 0x7c, 0x00, 0xc2, 0x62, 153 0x54, 0x08, 0x01, 0x00, 154 0x00, 0x06, 0x00, 0x08, // username attribute (length 8) 155 0x61, 0x62, 0x63, 0x64, // abcdefgh 156 0x65, 0x66, 0x67, 0x68 157 }; 158 159 // Message with an unknown but comprehensible optional attribute. 160 // Parsing should succeed despite this unknown attribute. 161 static const unsigned char kStunMessageWithUnknownAttribute[] = { 162 0x00, 0x01, 0x00, 0x14, 163 0x21, 0x12, 0xa4, 0x42, 164 0xe3, 0xa9, 0x46, 0xe1, 165 0x7c, 0x00, 0xc2, 0x62, 166 0x54, 0x08, 0x01, 0x00, 167 0x00, 0xaa, 0x00, 0x07, // Unknown attribute, length 7 (needs padding!) 168 0x61, 0x62, 0x63, 0x64, // abcdefg + padding 169 0x65, 0x66, 0x67, 0x00, 170 0x00, 0x06, 0x00, 0x03, // Followed by a known attribute we can 171 0x61, 0x62, 0x63, 0x00 // check for (username of length 3) 172 }; 173 174 // ByteString Attribute (username) with padding byte 175 static const unsigned char kStunMessageWithPaddedByteStringAttribute[] = { 176 0x00, 0x01, 0x00, 0x08, 177 0x21, 0x12, 0xa4, 0x42, 178 0xe3, 0xa9, 0x46, 0xe1, 179 0x7c, 0x00, 0xc2, 0x62, 180 0x54, 0x08, 0x01, 0x00, 181 0x00, 0x06, 0x00, 0x03, // username attribute (length 3) 182 0x61, 0x62, 0x63, 0xcc // abc 183 }; 184 185 // Message with an Unknown Attributes (uint16 list) attribute. 186 static const unsigned char kStunMessageWithUInt16ListAttribute[] = { 187 0x00, 0x01, 0x00, 0x0c, 188 0x21, 0x12, 0xa4, 0x42, 189 0xe3, 0xa9, 0x46, 0xe1, 190 0x7c, 0x00, 0xc2, 0x62, 191 0x54, 0x08, 0x01, 0x00, 192 0x00, 0x0a, 0x00, 0x06, // username attribute (length 6) 193 0x00, 0x01, 0x10, 0x00, // three attributes plus padding 194 0xAB, 0xCU, 0xBE, 0xEF 195 }; 196 197 // Error response message (unauthorized) 198 static const unsigned char kStunMessageWithErrorAttribute[] = { 199 0x01, 0x11, 0x00, 0x14, 200 0x21, 0x12, 0xa4, 0x42, 201 0x29, 0x1f, 0xcd, 0x7c, 202 0xba, 0x58, 0xab, 0xd7, 203 0xf2, 0x41, 0x01, 0x00, 204 0x00, 0x09, 0x00, 0x10, 205 0x00, 0x00, 0x04, 0x01, 206 0x55, 0x6e, 0x61, 0x75, 207 0x74, 0x68, 0x6f, 0x72, 208 0x69, 0x7a, 0x65, 0x64 209 }; 210 211 // Sample messages with an invalid length Field 212 213 // The actual length in bytes of the invalid messages (including STUN header) 214 static const int kRealLengthOfInvalidLengthTestCases = 32; 215 216 static const unsigned char kStunMessageWithZeroLength[] = { 217 0x00, 0x01, 0x00, 0x00, // length of 0 (last 2 bytes) 218 0x21, 0x12, 0xA4, 0x42, // magic cookie 219 '0', '1', '2', '3', // transaction id 220 '4', '5', '6', '7', 221 '8', '9', 'a', 'b', 222 0x00, 0x20, 0x00, 0x08, // xor mapped address 223 0x00, 0x01, 0x21, 0x1F, 224 0x21, 0x12, 0xA4, 0x53, 225 }; 226 227 static const unsigned char kStunMessageWithExcessLength[] = { 228 0x00, 0x01, 0x00, 0x55, // length of 85 229 0x21, 0x12, 0xA4, 0x42, // magic cookie 230 '0', '1', '2', '3', // transaction id 231 '4', '5', '6', '7', 232 '8', '9', 'a', 'b', 233 0x00, 0x20, 0x00, 0x08, // xor mapped address 234 0x00, 0x01, 0x21, 0x1F, 235 0x21, 0x12, 0xA4, 0x53, 236 }; 237 238 static const unsigned char kStunMessageWithSmallLength[] = { 239 0x00, 0x01, 0x00, 0x03, // length of 3 240 0x21, 0x12, 0xA4, 0x42, // magic cookie 241 '0', '1', '2', '3', // transaction id 242 '4', '5', '6', '7', 243 '8', '9', 'a', 'b', 244 0x00, 0x20, 0x00, 0x08, // xor mapped address 245 0x00, 0x01, 0x21, 0x1F, 246 0x21, 0x12, 0xA4, 0x53, 247 }; 248 249 // RTCP packet, for testing we correctly ignore non stun packet types. 250 // V=2, P=false, RC=0, Type=200, Len=6, Sender-SSRC=85, etc 251 static const unsigned char kRtcpPacket[] = { 252 0x80, 0xc8, 0x00, 0x06, 0x00, 0x00, 0x00, 0x55, 253 0xce, 0xa5, 0x18, 0x3a, 0x39, 0xcc, 0x7d, 0x09, 254 0x23, 0xed, 0x19, 0x07, 0x00, 0x00, 0x01, 0x56, 255 0x00, 0x03, 0x73, 0x50, 256 }; 257 258 // RFC5769 Test Vectors 259 // Software name (request): "STUN test client" (without quotes) 260 // Software name (response): "test vector" (without quotes) 261 // Username: "evtj:h6vY" (without quotes) 262 // Password: "VOkJxbRl1RmTxUk/WvJxBt" (without quotes) 263 static const unsigned char kRfc5769SampleMsgTransactionId[] = { 264 0xb7, 0xe7, 0xa7, 0x01, 0xbc, 0x34, 0xd6, 0x86, 0xfa, 0x87, 0xdf, 0xae 265 }; 266 static const char kRfc5769SampleMsgClientSoftware[] = "STUN test client"; 267 static const char kRfc5769SampleMsgServerSoftware[] = "test vector"; 268 static const char kRfc5769SampleMsgUsername[] = "evtj:h6vY"; 269 static const char kRfc5769SampleMsgPassword[] = "VOkJxbRl1RmTxUk/WvJxBt"; 270 static const talk_base::SocketAddress kRfc5769SampleMsgMappedAddress( 271 "192.0.2.1", 32853); 272 static const talk_base::SocketAddress kRfc5769SampleMsgIPv6MappedAddress( 273 "2001:db8:1234:5678:11:2233:4455:6677", 32853); 274 275 static const unsigned char kRfc5769SampleMsgWithAuthTransactionId[] = { 276 0x78, 0xad, 0x34, 0x33, 0xc6, 0xad, 0x72, 0xc0, 0x29, 0xda, 0x41, 0x2e 277 }; 278 static const char kRfc5769SampleMsgWithAuthUsername[] = 279 "\xe3\x83\x9e\xe3\x83\x88\xe3\x83\xaa\xe3\x83\x83\xe3\x82\xaf\xe3\x82\xb9"; 280 static const char kRfc5769SampleMsgWithAuthPassword[] = "TheMatrIX"; 281 static const char kRfc5769SampleMsgWithAuthNonce[] = 282 "f//499k954d6OL34oL9FSTvy64sA"; 283 static const char kRfc5769SampleMsgWithAuthRealm[] = "example.org"; 284 285 // 2.1. Sample Request 286 static const unsigned char kRfc5769SampleRequest[] = { 287 0x00, 0x01, 0x00, 0x58, // Request type and message length 288 0x21, 0x12, 0xa4, 0x42, // Magic cookie 289 0xb7, 0xe7, 0xa7, 0x01, // } 290 0xbc, 0x34, 0xd6, 0x86, // } Transaction ID 291 0xfa, 0x87, 0xdf, 0xae, // } 292 0x80, 0x22, 0x00, 0x10, // SOFTWARE attribute header 293 0x53, 0x54, 0x55, 0x4e, // } 294 0x20, 0x74, 0x65, 0x73, // } User-agent... 295 0x74, 0x20, 0x63, 0x6c, // } ...name 296 0x69, 0x65, 0x6e, 0x74, // } 297 0x00, 0x24, 0x00, 0x04, // PRIORITY attribute header 298 0x6e, 0x00, 0x01, 0xff, // ICE priority value 299 0x80, 0x29, 0x00, 0x08, // ICE-CONTROLLED attribute header 300 0x93, 0x2f, 0xf9, 0xb1, // } Pseudo-random tie breaker... 301 0x51, 0x26, 0x3b, 0x36, // } ...for ICE control 302 0x00, 0x06, 0x00, 0x09, // USERNAME attribute header 303 0x65, 0x76, 0x74, 0x6a, // } 304 0x3a, 0x68, 0x36, 0x76, // } Username (9 bytes) and padding (3 bytes) 305 0x59, 0x20, 0x20, 0x20, // } 306 0x00, 0x08, 0x00, 0x14, // MESSAGE-INTEGRITY attribute header 307 0x9a, 0xea, 0xa7, 0x0c, // } 308 0xbf, 0xd8, 0xcb, 0x56, // } 309 0x78, 0x1e, 0xf2, 0xb5, // } HMAC-SHA1 fingerprint 310 0xb2, 0xd3, 0xf2, 0x49, // } 311 0xc1, 0xb5, 0x71, 0xa2, // } 312 0x80, 0x28, 0x00, 0x04, // FINGERPRINT attribute header 313 0xe5, 0x7a, 0x3b, 0xcf // CRC32 fingerprint 314 }; 315 316 // 2.2. Sample IPv4 Response 317 static const unsigned char kRfc5769SampleResponse[] = { 318 0x01, 0x01, 0x00, 0x3c, // Response type and message length 319 0x21, 0x12, 0xa4, 0x42, // Magic cookie 320 0xb7, 0xe7, 0xa7, 0x01, // } 321 0xbc, 0x34, 0xd6, 0x86, // } Transaction ID 322 0xfa, 0x87, 0xdf, 0xae, // } 323 0x80, 0x22, 0x00, 0x0b, // SOFTWARE attribute header 324 0x74, 0x65, 0x73, 0x74, // } 325 0x20, 0x76, 0x65, 0x63, // } UTF-8 server name 326 0x74, 0x6f, 0x72, 0x20, // } 327 0x00, 0x20, 0x00, 0x08, // XOR-MAPPED-ADDRESS attribute header 328 0x00, 0x01, 0xa1, 0x47, // Address family (IPv4) and xor'd mapped port 329 0xe1, 0x12, 0xa6, 0x43, // Xor'd mapped IPv4 address 330 0x00, 0x08, 0x00, 0x14, // MESSAGE-INTEGRITY attribute header 331 0x2b, 0x91, 0xf5, 0x99, // } 332 0xfd, 0x9e, 0x90, 0xc3, // } 333 0x8c, 0x74, 0x89, 0xf9, // } HMAC-SHA1 fingerprint 334 0x2a, 0xf9, 0xba, 0x53, // } 335 0xf0, 0x6b, 0xe7, 0xd7, // } 336 0x80, 0x28, 0x00, 0x04, // FINGERPRINT attribute header 337 0xc0, 0x7d, 0x4c, 0x96 // CRC32 fingerprint 338 }; 339 340 // 2.3. Sample IPv6 Response 341 static const unsigned char kRfc5769SampleResponseIPv6[] = { 342 0x01, 0x01, 0x00, 0x48, // Response type and message length 343 0x21, 0x12, 0xa4, 0x42, // Magic cookie 344 0xb7, 0xe7, 0xa7, 0x01, // } 345 0xbc, 0x34, 0xd6, 0x86, // } Transaction ID 346 0xfa, 0x87, 0xdf, 0xae, // } 347 0x80, 0x22, 0x00, 0x0b, // SOFTWARE attribute header 348 0x74, 0x65, 0x73, 0x74, // } 349 0x20, 0x76, 0x65, 0x63, // } UTF-8 server name 350 0x74, 0x6f, 0x72, 0x20, // } 351 0x00, 0x20, 0x00, 0x14, // XOR-MAPPED-ADDRESS attribute header 352 0x00, 0x02, 0xa1, 0x47, // Address family (IPv6) and xor'd mapped port. 353 0x01, 0x13, 0xa9, 0xfa, // } 354 0xa5, 0xd3, 0xf1, 0x79, // } Xor'd mapped IPv6 address 355 0xbc, 0x25, 0xf4, 0xb5, // } 356 0xbe, 0xd2, 0xb9, 0xd9, // } 357 0x00, 0x08, 0x00, 0x14, // MESSAGE-INTEGRITY attribute header 358 0xa3, 0x82, 0x95, 0x4e, // } 359 0x4b, 0xe6, 0x7b, 0xf1, // } 360 0x17, 0x84, 0xc9, 0x7c, // } HMAC-SHA1 fingerprint 361 0x82, 0x92, 0xc2, 0x75, // } 362 0xbf, 0xe3, 0xed, 0x41, // } 363 0x80, 0x28, 0x00, 0x04, // FINGERPRINT attribute header 364 0xc8, 0xfb, 0x0b, 0x4c // CRC32 fingerprint 365 }; 366 367 // 2.4. Sample Request with Long-Term Authentication 368 static const unsigned char kRfc5769SampleRequestLongTermAuth[] = { 369 0x00, 0x01, 0x00, 0x60, // Request type and message length 370 0x21, 0x12, 0xa4, 0x42, // Magic cookie 371 0x78, 0xad, 0x34, 0x33, // } 372 0xc6, 0xad, 0x72, 0xc0, // } Transaction ID 373 0x29, 0xda, 0x41, 0x2e, // } 374 0x00, 0x06, 0x00, 0x12, // USERNAME attribute header 375 0xe3, 0x83, 0x9e, 0xe3, // } 376 0x83, 0x88, 0xe3, 0x83, // } 377 0xaa, 0xe3, 0x83, 0x83, // } Username value (18 bytes) and padding (2 bytes) 378 0xe3, 0x82, 0xaf, 0xe3, // } 379 0x82, 0xb9, 0x00, 0x00, // } 380 0x00, 0x15, 0x00, 0x1c, // NONCE attribute header 381 0x66, 0x2f, 0x2f, 0x34, // } 382 0x39, 0x39, 0x6b, 0x39, // } 383 0x35, 0x34, 0x64, 0x36, // } 384 0x4f, 0x4c, 0x33, 0x34, // } Nonce value 385 0x6f, 0x4c, 0x39, 0x46, // } 386 0x53, 0x54, 0x76, 0x79, // } 387 0x36, 0x34, 0x73, 0x41, // } 388 0x00, 0x14, 0x00, 0x0b, // REALM attribute header 389 0x65, 0x78, 0x61, 0x6d, // } 390 0x70, 0x6c, 0x65, 0x2e, // } Realm value (11 bytes) and padding (1 byte) 391 0x6f, 0x72, 0x67, 0x00, // } 392 0x00, 0x08, 0x00, 0x14, // MESSAGE-INTEGRITY attribute header 393 0xf6, 0x70, 0x24, 0x65, // } 394 0x6d, 0xd6, 0x4a, 0x3e, // } 395 0x02, 0xb8, 0xe0, 0x71, // } HMAC-SHA1 fingerprint 396 0x2e, 0x85, 0xc9, 0xa2, // } 397 0x8c, 0xa8, 0x96, 0x66 // } 398 }; 399 400 // Length parameter is changed to 0x38 from 0x58. 401 // AddMessageIntegrity will add MI information and update the length param 402 // accordingly. 403 static const unsigned char kRfc5769SampleRequestWithoutMI[] = { 404 0x00, 0x01, 0x00, 0x38, // Request type and message length 405 0x21, 0x12, 0xa4, 0x42, // Magic cookie 406 0xb7, 0xe7, 0xa7, 0x01, // } 407 0xbc, 0x34, 0xd6, 0x86, // } Transaction ID 408 0xfa, 0x87, 0xdf, 0xae, // } 409 0x80, 0x22, 0x00, 0x10, // SOFTWARE attribute header 410 0x53, 0x54, 0x55, 0x4e, // } 411 0x20, 0x74, 0x65, 0x73, // } User-agent... 412 0x74, 0x20, 0x63, 0x6c, // } ...name 413 0x69, 0x65, 0x6e, 0x74, // } 414 0x00, 0x24, 0x00, 0x04, // PRIORITY attribute header 415 0x6e, 0x00, 0x01, 0xff, // ICE priority value 416 0x80, 0x29, 0x00, 0x08, // ICE-CONTROLLED attribute header 417 0x93, 0x2f, 0xf9, 0xb1, // } Pseudo-random tie breaker... 418 0x51, 0x26, 0x3b, 0x36, // } ...for ICE control 419 0x00, 0x06, 0x00, 0x09, // USERNAME attribute header 420 0x65, 0x76, 0x74, 0x6a, // } 421 0x3a, 0x68, 0x36, 0x76, // } Username (9 bytes) and padding (3 bytes) 422 0x59, 0x20, 0x20, 0x20 // } 423 }; 424 425 // This HMAC differs from the RFC 5769 SampleRequest message. This differs 426 // because spec uses 0x20 for the padding where as our implementation uses 0. 427 static const unsigned char kCalculatedHmac1[] = { 428 0x79, 0x07, 0xc2, 0xd2, // } 429 0xed, 0xbf, 0xea, 0x48, // } 430 0x0e, 0x4c, 0x76, 0xd8, // } HMAC-SHA1 fingerprint 431 0x29, 0x62, 0xd5, 0xc3, // } 432 0x74, 0x2a, 0xf9, 0xe3 // } 433 }; 434 435 // Length parameter is changed to 0x1c from 0x3c. 436 // AddMessageIntegrity will add MI information and update the length param 437 // accordingly. 438 static const unsigned char kRfc5769SampleResponseWithoutMI[] = { 439 0x01, 0x01, 0x00, 0x1c, // Response type and message length 440 0x21, 0x12, 0xa4, 0x42, // Magic cookie 441 0xb7, 0xe7, 0xa7, 0x01, // } 442 0xbc, 0x34, 0xd6, 0x86, // } Transaction ID 443 0xfa, 0x87, 0xdf, 0xae, // } 444 0x80, 0x22, 0x00, 0x0b, // SOFTWARE attribute header 445 0x74, 0x65, 0x73, 0x74, // } 446 0x20, 0x76, 0x65, 0x63, // } UTF-8 server name 447 0x74, 0x6f, 0x72, 0x20, // } 448 0x00, 0x20, 0x00, 0x08, // XOR-MAPPED-ADDRESS attribute header 449 0x00, 0x01, 0xa1, 0x47, // Address family (IPv4) and xor'd mapped port 450 0xe1, 0x12, 0xa6, 0x43 // Xor'd mapped IPv4 address 451 }; 452 453 // This HMAC differs from the RFC 5769 SampleResponse message. This differs 454 // because spec uses 0x20 for the padding where as our implementation uses 0. 455 static const unsigned char kCalculatedHmac2[] = { 456 0x5d, 0x6b, 0x58, 0xbe, // } 457 0xad, 0x94, 0xe0, 0x7e, // } 458 0xef, 0x0d, 0xfc, 0x12, // } HMAC-SHA1 fingerprint 459 0x82, 0xa2, 0xbd, 0x08, // } 460 0x43, 0x14, 0x10, 0x28 // } 461 }; 462 463 // A transaction ID without the 'magic cookie' portion 464 // pjnat's test programs use this transaction ID a lot. 465 const unsigned char kTestTransactionId1[] = { 0x029, 0x01f, 0x0cd, 0x07c, 466 0x0ba, 0x058, 0x0ab, 0x0d7, 467 0x0f2, 0x041, 0x001, 0x000 }; 468 469 // They use this one sometimes too. 470 const unsigned char kTestTransactionId2[] = { 0x0e3, 0x0a9, 0x046, 0x0e1, 471 0x07c, 0x000, 0x0c2, 0x062, 472 0x054, 0x008, 0x001, 0x000 }; 473 474 const in6_addr kIPv6TestAddress1 = { { { 0x24, 0x01, 0xfa, 0x00, 475 0x00, 0x04, 0x10, 0x00, 476 0xbe, 0x30, 0x5b, 0xff, 477 0xfe, 0xe5, 0x00, 0xc3 } } }; 478 const in6_addr kIPv6TestAddress2 = { { { 0x24, 0x01, 0xfa, 0x00, 479 0x00, 0x04, 0x10, 0x12, 480 0x06, 0x0c, 0xce, 0xff, 481 0xfe, 0x1f, 0x61, 0xa4 } } }; 482 483 #ifdef POSIX 484 const in_addr kIPv4TestAddress1 = { 0xe64417ac }; 485 #elif defined WIN32 486 // Windows in_addr has a union with a uchar[] array first. 487 const in_addr kIPv4TestAddress1 = { { 0x0ac, 0x017, 0x044, 0x0e6 } }; 488 #endif 489 const char kTestUserName1[] = "abcdefgh"; 490 const char kTestUserName2[] = "abc"; 491 const char kTestErrorReason[] = "Unauthorized"; 492 const int kTestErrorClass = 4; 493 const int kTestErrorNumber = 1; 494 const int kTestErrorCode = 401; 495 496 const int kTestMessagePort1 = 59977; 497 const int kTestMessagePort2 = 47233; 498 const int kTestMessagePort3 = 56743; 499 const int kTestMessagePort4 = 40444; 500 501 #define ReadStunMessage(X, Y) ReadStunMessageTestCase(X, Y, sizeof(Y)); 502 503 // Test that the GetStun*Type and IsStun*Type methods work as expected. 504 TEST_F(StunTest, MessageTypes) { 505 EXPECT_EQ(STUN_BINDING_RESPONSE, 506 GetStunSuccessResponseType(STUN_BINDING_REQUEST)); 507 EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, 508 GetStunErrorResponseType(STUN_BINDING_REQUEST)); 509 EXPECT_EQ(-1, GetStunSuccessResponseType(STUN_BINDING_INDICATION)); 510 EXPECT_EQ(-1, GetStunSuccessResponseType(STUN_BINDING_RESPONSE)); 511 EXPECT_EQ(-1, GetStunSuccessResponseType(STUN_BINDING_ERROR_RESPONSE)); 512 EXPECT_EQ(-1, GetStunErrorResponseType(STUN_BINDING_INDICATION)); 513 EXPECT_EQ(-1, GetStunErrorResponseType(STUN_BINDING_RESPONSE)); 514 EXPECT_EQ(-1, GetStunErrorResponseType(STUN_BINDING_ERROR_RESPONSE)); 515 516 int types[] = { 517 STUN_BINDING_REQUEST, STUN_BINDING_INDICATION, 518 STUN_BINDING_RESPONSE, STUN_BINDING_ERROR_RESPONSE 519 }; 520 for (int i = 0; i < ARRAY_SIZE(types); ++i) { 521 EXPECT_EQ(i == 0, IsStunRequestType(types[i])); 522 EXPECT_EQ(i == 1, IsStunIndicationType(types[i])); 523 EXPECT_EQ(i == 2, IsStunSuccessResponseType(types[i])); 524 EXPECT_EQ(i == 3, IsStunErrorResponseType(types[i])); 525 EXPECT_EQ(1, types[i] & 0xFEEF); 526 } 527 } 528 529 TEST_F(StunTest, ReadMessageWithIPv4AddressAttribute) { 530 StunMessage msg; 531 size_t size = ReadStunMessage(&msg, kStunMessageWithIPv4MappedAddress); 532 CheckStunHeader(msg, STUN_BINDING_RESPONSE, size); 533 CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength); 534 535 const StunAddressAttribute* addr = msg.GetAddress(STUN_ATTR_MAPPED_ADDRESS); 536 talk_base::IPAddress test_address(kIPv4TestAddress1); 537 CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV4, 538 kTestMessagePort4, test_address); 539 } 540 541 TEST_F(StunTest, ReadMessageWithIPv4XorAddressAttribute) { 542 StunMessage msg; 543 StunMessage msg2; 544 size_t size = ReadStunMessage(&msg, kStunMessageWithIPv4XorMappedAddress); 545 CheckStunHeader(msg, STUN_BINDING_RESPONSE, size); 546 CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength); 547 548 const StunAddressAttribute* addr = 549 msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS); 550 talk_base::IPAddress test_address(kIPv4TestAddress1); 551 CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV4, 552 kTestMessagePort3, test_address); 553 } 554 555 TEST_F(StunTest, ReadMessageWithIPv6AddressAttribute) { 556 StunMessage msg; 557 size_t size = ReadStunMessage(&msg, kStunMessageWithIPv6MappedAddress); 558 CheckStunHeader(msg, STUN_BINDING_REQUEST, size); 559 CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength); 560 561 talk_base::IPAddress test_address(kIPv6TestAddress1); 562 563 const StunAddressAttribute* addr = msg.GetAddress(STUN_ATTR_MAPPED_ADDRESS); 564 CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV6, 565 kTestMessagePort2, test_address); 566 } 567 568 TEST_F(StunTest, ReadMessageWithInvalidAddressAttribute) { 569 StunMessage msg; 570 size_t size = ReadStunMessage(&msg, kStunMessageWithIPv6MappedAddress); 571 CheckStunHeader(msg, STUN_BINDING_REQUEST, size); 572 CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength); 573 574 talk_base::IPAddress test_address(kIPv6TestAddress1); 575 576 const StunAddressAttribute* addr = msg.GetAddress(STUN_ATTR_MAPPED_ADDRESS); 577 CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV6, 578 kTestMessagePort2, test_address); 579 } 580 581 TEST_F(StunTest, ReadMessageWithIPv6XorAddressAttribute) { 582 StunMessage msg; 583 size_t size = ReadStunMessage(&msg, kStunMessageWithIPv6XorMappedAddress); 584 585 talk_base::IPAddress test_address(kIPv6TestAddress1); 586 587 CheckStunHeader(msg, STUN_BINDING_RESPONSE, size); 588 CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength); 589 590 const StunAddressAttribute* addr = 591 msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS); 592 CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV6, 593 kTestMessagePort1, test_address); 594 } 595 596 // Read the RFC5389 fields from the RFC5769 sample STUN request. 597 TEST_F(StunTest, ReadRfc5769RequestMessage) { 598 StunMessage msg; 599 size_t size = ReadStunMessage(&msg, kRfc5769SampleRequest); 600 CheckStunHeader(msg, STUN_BINDING_REQUEST, size); 601 CheckStunTransactionID(msg, kRfc5769SampleMsgTransactionId, 602 kStunTransactionIdLength); 603 604 const StunByteStringAttribute* software = 605 msg.GetByteString(STUN_ATTR_SOFTWARE); 606 ASSERT_TRUE(software != NULL); 607 EXPECT_EQ(kRfc5769SampleMsgClientSoftware, software->GetString()); 608 609 const StunByteStringAttribute* username = 610 msg.GetByteString(STUN_ATTR_USERNAME); 611 ASSERT_TRUE(username != NULL); 612 EXPECT_EQ(kRfc5769SampleMsgUsername, username->GetString()); 613 614 // Actual M-I value checked in a later test. 615 ASSERT_TRUE(msg.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL); 616 617 // Fingerprint checked in a later test, but double-check the value here. 618 const StunUInt32Attribute* fingerprint = 619 msg.GetUInt32(STUN_ATTR_FINGERPRINT); 620 ASSERT_TRUE(fingerprint != NULL); 621 EXPECT_EQ(0xe57a3bcf, fingerprint->value()); 622 } 623 624 // Read the RFC5389 fields from the RFC5769 sample STUN response. 625 TEST_F(StunTest, ReadRfc5769ResponseMessage) { 626 StunMessage msg; 627 size_t size = ReadStunMessage(&msg, kRfc5769SampleResponse); 628 CheckStunHeader(msg, STUN_BINDING_RESPONSE, size); 629 CheckStunTransactionID(msg, kRfc5769SampleMsgTransactionId, 630 kStunTransactionIdLength); 631 632 const StunByteStringAttribute* software = 633 msg.GetByteString(STUN_ATTR_SOFTWARE); 634 ASSERT_TRUE(software != NULL); 635 EXPECT_EQ(kRfc5769SampleMsgServerSoftware, software->GetString()); 636 637 const StunAddressAttribute* mapped_address = 638 msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS); 639 ASSERT_TRUE(mapped_address != NULL); 640 EXPECT_EQ(kRfc5769SampleMsgMappedAddress, mapped_address->GetAddress()); 641 642 // Actual M-I and fingerprint checked in later tests. 643 ASSERT_TRUE(msg.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL); 644 ASSERT_TRUE(msg.GetUInt32(STUN_ATTR_FINGERPRINT) != NULL); 645 } 646 647 // Read the RFC5389 fields from the RFC5769 sample STUN response for IPv6. 648 TEST_F(StunTest, ReadRfc5769ResponseMessageIPv6) { 649 StunMessage msg; 650 size_t size = ReadStunMessage(&msg, kRfc5769SampleResponseIPv6); 651 CheckStunHeader(msg, STUN_BINDING_RESPONSE, size); 652 CheckStunTransactionID(msg, kRfc5769SampleMsgTransactionId, 653 kStunTransactionIdLength); 654 655 const StunByteStringAttribute* software = 656 msg.GetByteString(STUN_ATTR_SOFTWARE); 657 ASSERT_TRUE(software != NULL); 658 EXPECT_EQ(kRfc5769SampleMsgServerSoftware, software->GetString()); 659 660 const StunAddressAttribute* mapped_address = 661 msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS); 662 ASSERT_TRUE(mapped_address != NULL); 663 EXPECT_EQ(kRfc5769SampleMsgIPv6MappedAddress, mapped_address->GetAddress()); 664 665 // Actual M-I and fingerprint checked in later tests. 666 ASSERT_TRUE(msg.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL); 667 ASSERT_TRUE(msg.GetUInt32(STUN_ATTR_FINGERPRINT) != NULL); 668 } 669 670 // Read the RFC5389 fields from the RFC5769 sample STUN response with auth. 671 TEST_F(StunTest, ReadRfc5769RequestMessageLongTermAuth) { 672 StunMessage msg; 673 size_t size = ReadStunMessage(&msg, kRfc5769SampleRequestLongTermAuth); 674 CheckStunHeader(msg, STUN_BINDING_REQUEST, size); 675 CheckStunTransactionID(msg, kRfc5769SampleMsgWithAuthTransactionId, 676 kStunTransactionIdLength); 677 678 const StunByteStringAttribute* username = 679 msg.GetByteString(STUN_ATTR_USERNAME); 680 ASSERT_TRUE(username != NULL); 681 EXPECT_EQ(kRfc5769SampleMsgWithAuthUsername, username->GetString()); 682 683 const StunByteStringAttribute* nonce = 684 msg.GetByteString(STUN_ATTR_NONCE); 685 ASSERT_TRUE(nonce != NULL); 686 EXPECT_EQ(kRfc5769SampleMsgWithAuthNonce, nonce->GetString()); 687 688 const StunByteStringAttribute* realm = 689 msg.GetByteString(STUN_ATTR_REALM); 690 ASSERT_TRUE(realm != NULL); 691 EXPECT_EQ(kRfc5769SampleMsgWithAuthRealm, realm->GetString()); 692 693 // No fingerprint, actual M-I checked in later tests. 694 ASSERT_TRUE(msg.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL); 695 ASSERT_TRUE(msg.GetUInt32(STUN_ATTR_FINGERPRINT) == NULL); 696 } 697 698 // The RFC3489 packet in this test is the same as 699 // kStunMessageWithIPv4MappedAddress, but with a different value where the 700 // magic cookie was. 701 TEST_F(StunTest, ReadLegacyMessage) { 702 unsigned char rfc3489_packet[sizeof(kStunMessageWithIPv4MappedAddress)]; 703 memcpy(rfc3489_packet, kStunMessageWithIPv4MappedAddress, 704 sizeof(kStunMessageWithIPv4MappedAddress)); 705 // Overwrite the magic cookie here. 706 memcpy(&rfc3489_packet[4], "ABCD", 4); 707 708 StunMessage msg; 709 size_t size = ReadStunMessage(&msg, rfc3489_packet); 710 CheckStunHeader(msg, STUN_BINDING_RESPONSE, size); 711 CheckStunTransactionID(msg, &rfc3489_packet[4], kStunTransactionIdLength + 4); 712 713 const StunAddressAttribute* addr = msg.GetAddress(STUN_ATTR_MAPPED_ADDRESS); 714 talk_base::IPAddress test_address(kIPv4TestAddress1); 715 CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV4, 716 kTestMessagePort4, test_address); 717 } 718 719 TEST_F(StunTest, SetIPv6XorAddressAttributeOwner) { 720 StunMessage msg; 721 StunMessage msg2; 722 size_t size = ReadStunMessage(&msg, kStunMessageWithIPv6XorMappedAddress); 723 724 talk_base::IPAddress test_address(kIPv6TestAddress1); 725 726 CheckStunHeader(msg, STUN_BINDING_RESPONSE, size); 727 CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength); 728 729 const StunAddressAttribute* addr = 730 msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS); 731 CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV6, 732 kTestMessagePort1, test_address); 733 734 // Owner with a different transaction ID. 735 msg2.SetTransactionID("ABCDABCDABCD"); 736 StunXorAddressAttribute addr2(STUN_ATTR_XOR_MAPPED_ADDRESS, 20, NULL); 737 addr2.SetIP(addr->ipaddr()); 738 addr2.SetPort(addr->port()); 739 addr2.SetOwner(&msg2); 740 // The internal IP address shouldn't change. 741 ASSERT_EQ(addr2.ipaddr(), addr->ipaddr()); 742 743 talk_base::ByteBuffer correct_buf; 744 talk_base::ByteBuffer wrong_buf; 745 EXPECT_TRUE(addr->Write(&correct_buf)); 746 EXPECT_TRUE(addr2.Write(&wrong_buf)); 747 // But when written out, the buffers should look different. 748 ASSERT_NE(0, 749 memcmp(correct_buf.Data(), wrong_buf.Data(), wrong_buf.Length())); 750 // And when reading a known good value, the address should be wrong. 751 addr2.Read(&correct_buf); 752 ASSERT_NE(addr->ipaddr(), addr2.ipaddr()); 753 addr2.SetIP(addr->ipaddr()); 754 addr2.SetPort(addr->port()); 755 // Try writing with no owner at all, should fail and write nothing. 756 addr2.SetOwner(NULL); 757 ASSERT_EQ(addr2.ipaddr(), addr->ipaddr()); 758 wrong_buf.Consume(wrong_buf.Length()); 759 EXPECT_FALSE(addr2.Write(&wrong_buf)); 760 ASSERT_EQ(0U, wrong_buf.Length()); 761 } 762 763 TEST_F(StunTest, SetIPv4XorAddressAttributeOwner) { 764 // Unlike the IPv6XorAddressAttributeOwner test, IPv4 XOR address attributes 765 // should _not_ be affected by a change in owner. IPv4 XOR address uses the 766 // magic cookie value which is fixed. 767 StunMessage msg; 768 StunMessage msg2; 769 size_t size = ReadStunMessage(&msg, kStunMessageWithIPv4XorMappedAddress); 770 771 talk_base::IPAddress test_address(kIPv4TestAddress1); 772 773 CheckStunHeader(msg, STUN_BINDING_RESPONSE, size); 774 CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength); 775 776 const StunAddressAttribute* addr = 777 msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS); 778 CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV4, 779 kTestMessagePort3, test_address); 780 781 // Owner with a different transaction ID. 782 msg2.SetTransactionID("ABCDABCDABCD"); 783 StunXorAddressAttribute addr2(STUN_ATTR_XOR_MAPPED_ADDRESS, 20, NULL); 784 addr2.SetIP(addr->ipaddr()); 785 addr2.SetPort(addr->port()); 786 addr2.SetOwner(&msg2); 787 // The internal IP address shouldn't change. 788 ASSERT_EQ(addr2.ipaddr(), addr->ipaddr()); 789 790 talk_base::ByteBuffer correct_buf; 791 talk_base::ByteBuffer wrong_buf; 792 EXPECT_TRUE(addr->Write(&correct_buf)); 793 EXPECT_TRUE(addr2.Write(&wrong_buf)); 794 // The same address data should be written. 795 ASSERT_EQ(0, 796 memcmp(correct_buf.Data(), wrong_buf.Data(), wrong_buf.Length())); 797 // And an attribute should be able to un-XOR an address belonging to a message 798 // with a different transaction ID. 799 EXPECT_TRUE(addr2.Read(&correct_buf)); 800 ASSERT_EQ(addr->ipaddr(), addr2.ipaddr()); 801 802 // However, no owner is still an error, should fail and write nothing. 803 addr2.SetOwner(NULL); 804 ASSERT_EQ(addr2.ipaddr(), addr->ipaddr()); 805 wrong_buf.Consume(wrong_buf.Length()); 806 EXPECT_FALSE(addr2.Write(&wrong_buf)); 807 } 808 809 TEST_F(StunTest, CreateIPv6AddressAttribute) { 810 talk_base::IPAddress test_ip(kIPv6TestAddress2); 811 812 StunAddressAttribute* addr = 813 StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS); 814 talk_base::SocketAddress test_addr(test_ip, kTestMessagePort2); 815 addr->SetAddress(test_addr); 816 817 CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV6, 818 kTestMessagePort2, test_ip); 819 delete addr; 820 } 821 822 TEST_F(StunTest, CreateIPv4AddressAttribute) { 823 struct in_addr test_in_addr; 824 test_in_addr.s_addr = 0xBEB0B0BE; 825 talk_base::IPAddress test_ip(test_in_addr); 826 827 StunAddressAttribute* addr = 828 StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS); 829 talk_base::SocketAddress test_addr(test_ip, kTestMessagePort2); 830 addr->SetAddress(test_addr); 831 832 CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV4, 833 kTestMessagePort2, test_ip); 834 delete addr; 835 } 836 837 // Test that we don't care what order we set the parts of an address 838 TEST_F(StunTest, CreateAddressInArbitraryOrder) { 839 StunAddressAttribute* addr = 840 StunAttribute::CreateAddress(STUN_ATTR_DESTINATION_ADDRESS); 841 // Port first 842 addr->SetPort(kTestMessagePort1); 843 addr->SetIP(talk_base::IPAddress(kIPv4TestAddress1)); 844 ASSERT_EQ(kTestMessagePort1, addr->port()); 845 ASSERT_EQ(talk_base::IPAddress(kIPv4TestAddress1), addr->ipaddr()); 846 847 StunAddressAttribute* addr2 = 848 StunAttribute::CreateAddress(STUN_ATTR_DESTINATION_ADDRESS); 849 // IP first 850 addr2->SetIP(talk_base::IPAddress(kIPv4TestAddress1)); 851 addr2->SetPort(kTestMessagePort2); 852 ASSERT_EQ(kTestMessagePort2, addr2->port()); 853 ASSERT_EQ(talk_base::IPAddress(kIPv4TestAddress1), addr2->ipaddr()); 854 855 delete addr; 856 delete addr2; 857 } 858 859 TEST_F(StunTest, WriteMessageWithIPv6AddressAttribute) { 860 StunMessage msg; 861 size_t size = sizeof(kStunMessageWithIPv6MappedAddress); 862 863 talk_base::IPAddress test_ip(kIPv6TestAddress1); 864 865 msg.SetType(STUN_BINDING_REQUEST); 866 msg.SetTransactionID( 867 std::string(reinterpret_cast<const char*>(kTestTransactionId1), 868 kStunTransactionIdLength)); 869 CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength); 870 871 StunAddressAttribute* addr = 872 StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS); 873 talk_base::SocketAddress test_addr(test_ip, kTestMessagePort2); 874 addr->SetAddress(test_addr); 875 EXPECT_TRUE(msg.AddAttribute(addr)); 876 877 CheckStunHeader(msg, STUN_BINDING_REQUEST, (size - 20)); 878 879 talk_base::ByteBuffer out; 880 EXPECT_TRUE(msg.Write(&out)); 881 ASSERT_EQ(out.Length(), sizeof(kStunMessageWithIPv6MappedAddress)); 882 int len1 = static_cast<int>(out.Length()); 883 std::string bytes; 884 out.ReadString(&bytes, len1); 885 ASSERT_EQ(0, memcmp(bytes.c_str(), kStunMessageWithIPv6MappedAddress, len1)); 886 } 887 888 TEST_F(StunTest, WriteMessageWithIPv4AddressAttribute) { 889 StunMessage msg; 890 size_t size = sizeof(kStunMessageWithIPv4MappedAddress); 891 892 talk_base::IPAddress test_ip(kIPv4TestAddress1); 893 894 msg.SetType(STUN_BINDING_RESPONSE); 895 msg.SetTransactionID( 896 std::string(reinterpret_cast<const char*>(kTestTransactionId1), 897 kStunTransactionIdLength)); 898 CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength); 899 900 StunAddressAttribute* addr = 901 StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS); 902 talk_base::SocketAddress test_addr(test_ip, kTestMessagePort4); 903 addr->SetAddress(test_addr); 904 EXPECT_TRUE(msg.AddAttribute(addr)); 905 906 CheckStunHeader(msg, STUN_BINDING_RESPONSE, (size - 20)); 907 908 talk_base::ByteBuffer out; 909 EXPECT_TRUE(msg.Write(&out)); 910 ASSERT_EQ(out.Length(), sizeof(kStunMessageWithIPv4MappedAddress)); 911 int len1 = static_cast<int>(out.Length()); 912 std::string bytes; 913 out.ReadString(&bytes, len1); 914 ASSERT_EQ(0, memcmp(bytes.c_str(), kStunMessageWithIPv4MappedAddress, len1)); 915 } 916 917 TEST_F(StunTest, WriteMessageWithIPv6XorAddressAttribute) { 918 StunMessage msg; 919 size_t size = sizeof(kStunMessageWithIPv6XorMappedAddress); 920 921 talk_base::IPAddress test_ip(kIPv6TestAddress1); 922 923 msg.SetType(STUN_BINDING_RESPONSE); 924 msg.SetTransactionID( 925 std::string(reinterpret_cast<const char*>(kTestTransactionId2), 926 kStunTransactionIdLength)); 927 CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength); 928 929 StunAddressAttribute* addr = 930 StunAttribute::CreateXorAddress(STUN_ATTR_XOR_MAPPED_ADDRESS); 931 talk_base::SocketAddress test_addr(test_ip, kTestMessagePort1); 932 addr->SetAddress(test_addr); 933 EXPECT_TRUE(msg.AddAttribute(addr)); 934 935 CheckStunHeader(msg, STUN_BINDING_RESPONSE, (size - 20)); 936 937 talk_base::ByteBuffer out; 938 EXPECT_TRUE(msg.Write(&out)); 939 ASSERT_EQ(out.Length(), sizeof(kStunMessageWithIPv6XorMappedAddress)); 940 int len1 = static_cast<int>(out.Length()); 941 std::string bytes; 942 out.ReadString(&bytes, len1); 943 ASSERT_EQ(0, 944 memcmp(bytes.c_str(), kStunMessageWithIPv6XorMappedAddress, len1)); 945 } 946 947 TEST_F(StunTest, WriteMessageWithIPv4XoreAddressAttribute) { 948 StunMessage msg; 949 size_t size = sizeof(kStunMessageWithIPv4XorMappedAddress); 950 951 talk_base::IPAddress test_ip(kIPv4TestAddress1); 952 953 msg.SetType(STUN_BINDING_RESPONSE); 954 msg.SetTransactionID( 955 std::string(reinterpret_cast<const char*>(kTestTransactionId1), 956 kStunTransactionIdLength)); 957 CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength); 958 959 StunAddressAttribute* addr = 960 StunAttribute::CreateXorAddress(STUN_ATTR_XOR_MAPPED_ADDRESS); 961 talk_base::SocketAddress test_addr(test_ip, kTestMessagePort3); 962 addr->SetAddress(test_addr); 963 EXPECT_TRUE(msg.AddAttribute(addr)); 964 965 CheckStunHeader(msg, STUN_BINDING_RESPONSE, (size - 20)); 966 967 talk_base::ByteBuffer out; 968 EXPECT_TRUE(msg.Write(&out)); 969 ASSERT_EQ(out.Length(), sizeof(kStunMessageWithIPv4XorMappedAddress)); 970 int len1 = static_cast<int>(out.Length()); 971 std::string bytes; 972 out.ReadString(&bytes, len1); 973 ASSERT_EQ(0, 974 memcmp(bytes.c_str(), kStunMessageWithIPv4XorMappedAddress, len1)); 975 } 976 977 TEST_F(StunTest, ReadByteStringAttribute) { 978 StunMessage msg; 979 size_t size = ReadStunMessage(&msg, kStunMessageWithByteStringAttribute); 980 981 CheckStunHeader(msg, STUN_BINDING_REQUEST, size); 982 CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength); 983 const StunByteStringAttribute* username = 984 msg.GetByteString(STUN_ATTR_USERNAME); 985 ASSERT_TRUE(username != NULL); 986 EXPECT_EQ(kTestUserName1, username->GetString()); 987 } 988 989 TEST_F(StunTest, ReadPaddedByteStringAttribute) { 990 StunMessage msg; 991 size_t size = ReadStunMessage(&msg, 992 kStunMessageWithPaddedByteStringAttribute); 993 ASSERT_NE(0U, size); 994 CheckStunHeader(msg, STUN_BINDING_REQUEST, size); 995 CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength); 996 const StunByteStringAttribute* username = 997 msg.GetByteString(STUN_ATTR_USERNAME); 998 ASSERT_TRUE(username != NULL); 999 EXPECT_EQ(kTestUserName2, username->GetString()); 1000 } 1001 1002 TEST_F(StunTest, ReadErrorCodeAttribute) { 1003 StunMessage msg; 1004 size_t size = ReadStunMessage(&msg, kStunMessageWithErrorAttribute); 1005 1006 CheckStunHeader(msg, STUN_BINDING_ERROR_RESPONSE, size); 1007 CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength); 1008 const StunErrorCodeAttribute* errorcode = msg.GetErrorCode(); 1009 ASSERT_TRUE(errorcode != NULL); 1010 EXPECT_EQ(kTestErrorClass, errorcode->eclass()); 1011 EXPECT_EQ(kTestErrorNumber, errorcode->number()); 1012 EXPECT_EQ(kTestErrorReason, errorcode->reason()); 1013 EXPECT_EQ(kTestErrorCode, errorcode->code()); 1014 } 1015 1016 TEST_F(StunTest, ReadMessageWithAUInt16ListAttribute) { 1017 StunMessage msg; 1018 size_t size = ReadStunMessage(&msg, kStunMessageWithUInt16ListAttribute); 1019 CheckStunHeader(msg, STUN_BINDING_REQUEST, size); 1020 const StunUInt16ListAttribute* types = msg.GetUnknownAttributes(); 1021 ASSERT_TRUE(types != NULL); 1022 EXPECT_EQ(3U, types->Size()); 1023 EXPECT_EQ(0x1U, types->GetType(0)); 1024 EXPECT_EQ(0x1000U, types->GetType(1)); 1025 EXPECT_EQ(0xAB0CU, types->GetType(2)); 1026 } 1027 1028 TEST_F(StunTest, ReadMessageWithAnUnknownAttribute) { 1029 StunMessage msg; 1030 size_t size = ReadStunMessage(&msg, kStunMessageWithUnknownAttribute); 1031 CheckStunHeader(msg, STUN_BINDING_REQUEST, size); 1032 1033 // Parsing should have succeeded and there should be a USERNAME attribute 1034 const StunByteStringAttribute* username = 1035 msg.GetByteString(STUN_ATTR_USERNAME); 1036 ASSERT_TRUE(username != NULL); 1037 EXPECT_EQ(kTestUserName2, username->GetString()); 1038 } 1039 1040 TEST_F(StunTest, WriteMessageWithAnErrorCodeAttribute) { 1041 StunMessage msg; 1042 size_t size = sizeof(kStunMessageWithErrorAttribute); 1043 1044 msg.SetType(STUN_BINDING_ERROR_RESPONSE); 1045 msg.SetTransactionID( 1046 std::string(reinterpret_cast<const char*>(kTestTransactionId1), 1047 kStunTransactionIdLength)); 1048 CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength); 1049 StunErrorCodeAttribute* errorcode = StunAttribute::CreateErrorCode(); 1050 errorcode->SetCode(kTestErrorCode); 1051 errorcode->SetReason(kTestErrorReason); 1052 EXPECT_TRUE(msg.AddAttribute(errorcode)); 1053 CheckStunHeader(msg, STUN_BINDING_ERROR_RESPONSE, (size - 20)); 1054 1055 talk_base::ByteBuffer out; 1056 EXPECT_TRUE(msg.Write(&out)); 1057 ASSERT_EQ(size, out.Length()); 1058 // No padding. 1059 ASSERT_EQ(0, memcmp(out.Data(), kStunMessageWithErrorAttribute, size)); 1060 } 1061 1062 TEST_F(StunTest, WriteMessageWithAUInt16ListAttribute) { 1063 StunMessage msg; 1064 size_t size = sizeof(kStunMessageWithUInt16ListAttribute); 1065 1066 msg.SetType(STUN_BINDING_REQUEST); 1067 msg.SetTransactionID( 1068 std::string(reinterpret_cast<const char*>(kTestTransactionId2), 1069 kStunTransactionIdLength)); 1070 CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength); 1071 StunUInt16ListAttribute* list = StunAttribute::CreateUnknownAttributes(); 1072 list->AddType(0x1U); 1073 list->AddType(0x1000U); 1074 list->AddType(0xAB0CU); 1075 EXPECT_TRUE(msg.AddAttribute(list)); 1076 CheckStunHeader(msg, STUN_BINDING_REQUEST, (size - 20)); 1077 1078 talk_base::ByteBuffer out; 1079 EXPECT_TRUE(msg.Write(&out)); 1080 ASSERT_EQ(size, out.Length()); 1081 // Check everything up to the padding. 1082 ASSERT_EQ(0, 1083 memcmp(out.Data(), kStunMessageWithUInt16ListAttribute, size - 2)); 1084 } 1085 1086 // Test that we fail to read messages with invalid lengths. 1087 void CheckFailureToRead(const unsigned char* testcase, size_t length) { 1088 StunMessage msg; 1089 const char* input = reinterpret_cast<const char*>(testcase); 1090 talk_base::ByteBuffer buf(input, length); 1091 ASSERT_FALSE(msg.Read(&buf)); 1092 } 1093 1094 TEST_F(StunTest, FailToReadInvalidMessages) { 1095 CheckFailureToRead(kStunMessageWithZeroLength, 1096 kRealLengthOfInvalidLengthTestCases); 1097 CheckFailureToRead(kStunMessageWithSmallLength, 1098 kRealLengthOfInvalidLengthTestCases); 1099 CheckFailureToRead(kStunMessageWithExcessLength, 1100 kRealLengthOfInvalidLengthTestCases); 1101 } 1102 1103 // Test that we properly fail to read a non-STUN message. 1104 TEST_F(StunTest, FailToReadRtcpPacket) { 1105 CheckFailureToRead(kRtcpPacket, sizeof(kRtcpPacket)); 1106 } 1107 1108 // Check our STUN message validation code against the RFC5769 test messages. 1109 TEST_F(StunTest, ValidateMessageIntegrity) { 1110 // Try the messages from RFC 5769. 1111 EXPECT_TRUE(StunMessage::ValidateMessageIntegrity( 1112 reinterpret_cast<const char*>(kRfc5769SampleRequest), 1113 sizeof(kRfc5769SampleRequest), 1114 kRfc5769SampleMsgPassword)); 1115 EXPECT_FALSE(StunMessage::ValidateMessageIntegrity( 1116 reinterpret_cast<const char*>(kRfc5769SampleRequest), 1117 sizeof(kRfc5769SampleRequest), 1118 "InvalidPassword")); 1119 1120 EXPECT_TRUE(StunMessage::ValidateMessageIntegrity( 1121 reinterpret_cast<const char*>(kRfc5769SampleResponse), 1122 sizeof(kRfc5769SampleResponse), 1123 kRfc5769SampleMsgPassword)); 1124 EXPECT_FALSE(StunMessage::ValidateMessageIntegrity( 1125 reinterpret_cast<const char*>(kRfc5769SampleResponse), 1126 sizeof(kRfc5769SampleResponse), 1127 "InvalidPassword")); 1128 1129 EXPECT_TRUE(StunMessage::ValidateMessageIntegrity( 1130 reinterpret_cast<const char*>(kRfc5769SampleResponseIPv6), 1131 sizeof(kRfc5769SampleResponseIPv6), 1132 kRfc5769SampleMsgPassword)); 1133 EXPECT_FALSE(StunMessage::ValidateMessageIntegrity( 1134 reinterpret_cast<const char*>(kRfc5769SampleResponseIPv6), 1135 sizeof(kRfc5769SampleResponseIPv6), 1136 "InvalidPassword")); 1137 1138 // We first need to compute the key for the long-term authentication HMAC. 1139 std::string key; 1140 ComputeStunCredentialHash(kRfc5769SampleMsgWithAuthUsername, 1141 kRfc5769SampleMsgWithAuthRealm, kRfc5769SampleMsgWithAuthPassword, &key); 1142 EXPECT_TRUE(StunMessage::ValidateMessageIntegrity( 1143 reinterpret_cast<const char*>(kRfc5769SampleRequestLongTermAuth), 1144 sizeof(kRfc5769SampleRequestLongTermAuth), key)); 1145 EXPECT_FALSE(StunMessage::ValidateMessageIntegrity( 1146 reinterpret_cast<const char*>(kRfc5769SampleRequestLongTermAuth), 1147 sizeof(kRfc5769SampleRequestLongTermAuth), 1148 "InvalidPassword")); 1149 1150 // Try some edge cases. 1151 EXPECT_FALSE(StunMessage::ValidateMessageIntegrity( 1152 reinterpret_cast<const char*>(kStunMessageWithZeroLength), 1153 sizeof(kStunMessageWithZeroLength), 1154 kRfc5769SampleMsgPassword)); 1155 EXPECT_FALSE(StunMessage::ValidateMessageIntegrity( 1156 reinterpret_cast<const char*>(kStunMessageWithExcessLength), 1157 sizeof(kStunMessageWithExcessLength), 1158 kRfc5769SampleMsgPassword)); 1159 EXPECT_FALSE(StunMessage::ValidateMessageIntegrity( 1160 reinterpret_cast<const char*>(kStunMessageWithSmallLength), 1161 sizeof(kStunMessageWithSmallLength), 1162 kRfc5769SampleMsgPassword)); 1163 1164 // Test that munging a single bit anywhere in the message causes the 1165 // message-integrity check to fail, unless it is after the M-I attribute. 1166 char buf[sizeof(kRfc5769SampleRequest)]; 1167 memcpy(buf, kRfc5769SampleRequest, sizeof(kRfc5769SampleRequest)); 1168 for (size_t i = 0; i < sizeof(buf); ++i) { 1169 buf[i] ^= 0x01; 1170 if (i > 0) 1171 buf[i - 1] ^= 0x01; 1172 EXPECT_EQ(i >= sizeof(buf) - 8, StunMessage::ValidateMessageIntegrity( 1173 buf, sizeof(buf), kRfc5769SampleMsgPassword)); 1174 } 1175 } 1176 1177 // Validate that we generate correct MESSAGE-INTEGRITY attributes. 1178 // Note the use of IceMessage instead of StunMessage; this is necessary because 1179 // the RFC5769 test messages used include attributes not found in basic STUN. 1180 TEST_F(StunTest, AddMessageIntegrity) { 1181 IceMessage msg; 1182 talk_base::ByteBuffer buf( 1183 reinterpret_cast<const char*>(kRfc5769SampleRequestWithoutMI), 1184 sizeof(kRfc5769SampleRequestWithoutMI)); 1185 EXPECT_TRUE(msg.Read(&buf)); 1186 EXPECT_TRUE(msg.AddMessageIntegrity(kRfc5769SampleMsgPassword)); 1187 const StunByteStringAttribute* mi_attr = 1188 msg.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY); 1189 EXPECT_EQ(20U, mi_attr->length()); 1190 EXPECT_EQ(0, memcmp( 1191 mi_attr->bytes(), kCalculatedHmac1, sizeof(kCalculatedHmac1))); 1192 1193 talk_base::ByteBuffer buf1; 1194 EXPECT_TRUE(msg.Write(&buf1)); 1195 EXPECT_TRUE(StunMessage::ValidateMessageIntegrity( 1196 reinterpret_cast<const char*>(buf1.Data()), buf1.Length(), 1197 kRfc5769SampleMsgPassword)); 1198 1199 IceMessage msg2; 1200 talk_base::ByteBuffer buf2( 1201 reinterpret_cast<const char*>(kRfc5769SampleResponseWithoutMI), 1202 sizeof(kRfc5769SampleResponseWithoutMI)); 1203 EXPECT_TRUE(msg2.Read(&buf2)); 1204 EXPECT_TRUE(msg2.AddMessageIntegrity(kRfc5769SampleMsgPassword)); 1205 const StunByteStringAttribute* mi_attr2 = 1206 msg2.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY); 1207 EXPECT_EQ(20U, mi_attr2->length()); 1208 EXPECT_EQ( 1209 0, memcmp(mi_attr2->bytes(), kCalculatedHmac2, sizeof(kCalculatedHmac2))); 1210 1211 talk_base::ByteBuffer buf3; 1212 EXPECT_TRUE(msg2.Write(&buf3)); 1213 EXPECT_TRUE(StunMessage::ValidateMessageIntegrity( 1214 reinterpret_cast<const char*>(buf3.Data()), buf3.Length(), 1215 kRfc5769SampleMsgPassword)); 1216 } 1217 1218 // Check our STUN message validation code against the RFC5769 test messages. 1219 TEST_F(StunTest, ValidateFingerprint) { 1220 EXPECT_TRUE(StunMessage::ValidateFingerprint( 1221 reinterpret_cast<const char*>(kRfc5769SampleRequest), 1222 sizeof(kRfc5769SampleRequest))); 1223 EXPECT_TRUE(StunMessage::ValidateFingerprint( 1224 reinterpret_cast<const char*>(kRfc5769SampleResponse), 1225 sizeof(kRfc5769SampleResponse))); 1226 EXPECT_TRUE(StunMessage::ValidateFingerprint( 1227 reinterpret_cast<const char*>(kRfc5769SampleResponseIPv6), 1228 sizeof(kRfc5769SampleResponseIPv6))); 1229 1230 EXPECT_FALSE(StunMessage::ValidateFingerprint( 1231 reinterpret_cast<const char*>(kStunMessageWithZeroLength), 1232 sizeof(kStunMessageWithZeroLength))); 1233 EXPECT_FALSE(StunMessage::ValidateFingerprint( 1234 reinterpret_cast<const char*>(kStunMessageWithExcessLength), 1235 sizeof(kStunMessageWithExcessLength))); 1236 EXPECT_FALSE(StunMessage::ValidateFingerprint( 1237 reinterpret_cast<const char*>(kStunMessageWithSmallLength), 1238 sizeof(kStunMessageWithSmallLength))); 1239 1240 // Test that munging a single bit anywhere in the message causes the 1241 // fingerprint check to fail. 1242 char buf[sizeof(kRfc5769SampleRequest)]; 1243 memcpy(buf, kRfc5769SampleRequest, sizeof(kRfc5769SampleRequest)); 1244 for (size_t i = 0; i < sizeof(buf); ++i) { 1245 buf[i] ^= 0x01; 1246 if (i > 0) 1247 buf[i - 1] ^= 0x01; 1248 EXPECT_FALSE(StunMessage::ValidateFingerprint(buf, sizeof(buf))); 1249 } 1250 // Put them all back to normal and the check should pass again. 1251 buf[sizeof(buf) - 1] ^= 0x01; 1252 EXPECT_TRUE(StunMessage::ValidateFingerprint(buf, sizeof(buf))); 1253 } 1254 1255 TEST_F(StunTest, AddFingerprint) { 1256 IceMessage msg; 1257 talk_base::ByteBuffer buf( 1258 reinterpret_cast<const char*>(kRfc5769SampleRequestWithoutMI), 1259 sizeof(kRfc5769SampleRequestWithoutMI)); 1260 EXPECT_TRUE(msg.Read(&buf)); 1261 EXPECT_TRUE(msg.AddFingerprint()); 1262 1263 talk_base::ByteBuffer buf1; 1264 EXPECT_TRUE(msg.Write(&buf1)); 1265 EXPECT_TRUE(StunMessage::ValidateFingerprint( 1266 reinterpret_cast<const char*>(buf1.Data()), buf1.Length())); 1267 } 1268 1269 // Sample "GTURN" relay message. 1270 static const unsigned char kRelayMessage[] = { 1271 0x00, 0x01, 0x00, 88, // message header 1272 0x21, 0x12, 0xA4, 0x42, // magic cookie 1273 '0', '1', '2', '3', // transaction id 1274 '4', '5', '6', '7', 1275 '8', '9', 'a', 'b', 1276 0x00, 0x01, 0x00, 8, // mapped address 1277 0x00, 0x01, 0x00, 13, 1278 0x00, 0x00, 0x00, 17, 1279 0x00, 0x06, 0x00, 12, // username 1280 'a', 'b', 'c', 'd', 1281 'e', 'f', 'g', 'h', 1282 'i', 'j', 'k', 'l', 1283 0x00, 0x0d, 0x00, 4, // lifetime 1284 0x00, 0x00, 0x00, 11, 1285 0x00, 0x0f, 0x00, 4, // magic cookie 1286 0x72, 0xc6, 0x4b, 0xc6, 1287 0x00, 0x10, 0x00, 4, // bandwidth 1288 0x00, 0x00, 0x00, 6, 1289 0x00, 0x11, 0x00, 8, // destination address 1290 0x00, 0x01, 0x00, 13, 1291 0x00, 0x00, 0x00, 17, 1292 0x00, 0x12, 0x00, 8, // source address 2 1293 0x00, 0x01, 0x00, 13, 1294 0x00, 0x00, 0x00, 17, 1295 0x00, 0x13, 0x00, 7, // data 1296 'a', 'b', 'c', 'd', 1297 'e', 'f', 'g', 0 // DATA must be padded per rfc5766. 1298 }; 1299 1300 // Test that we can read the GTURN-specific fields. 1301 TEST_F(StunTest, ReadRelayMessage) { 1302 RelayMessage msg, msg2; 1303 1304 const char* input = reinterpret_cast<const char*>(kRelayMessage); 1305 size_t size = sizeof(kRelayMessage); 1306 talk_base::ByteBuffer buf(input, size); 1307 EXPECT_TRUE(msg.Read(&buf)); 1308 1309 EXPECT_EQ(STUN_BINDING_REQUEST, msg.type()); 1310 EXPECT_EQ(size - 20, msg.length()); 1311 EXPECT_EQ("0123456789ab", msg.transaction_id()); 1312 1313 msg2.SetType(STUN_BINDING_REQUEST); 1314 msg2.SetTransactionID("0123456789ab"); 1315 1316 in_addr legacy_in_addr; 1317 legacy_in_addr.s_addr = htonl(17U); 1318 talk_base::IPAddress legacy_ip(legacy_in_addr); 1319 1320 const StunAddressAttribute* addr = msg.GetAddress(STUN_ATTR_MAPPED_ADDRESS); 1321 ASSERT_TRUE(addr != NULL); 1322 EXPECT_EQ(1, addr->family()); 1323 EXPECT_EQ(13, addr->port()); 1324 EXPECT_EQ(legacy_ip, addr->ipaddr()); 1325 1326 StunAddressAttribute* addr2 = 1327 StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS); 1328 addr2->SetPort(13); 1329 addr2->SetIP(legacy_ip); 1330 EXPECT_TRUE(msg2.AddAttribute(addr2)); 1331 1332 const StunByteStringAttribute* bytes = msg.GetByteString(STUN_ATTR_USERNAME); 1333 ASSERT_TRUE(bytes != NULL); 1334 EXPECT_EQ(12U, bytes->length()); 1335 EXPECT_EQ("abcdefghijkl", bytes->GetString()); 1336 1337 StunByteStringAttribute* bytes2 = 1338 StunAttribute::CreateByteString(STUN_ATTR_USERNAME); 1339 bytes2->CopyBytes("abcdefghijkl"); 1340 EXPECT_TRUE(msg2.AddAttribute(bytes2)); 1341 1342 const StunUInt32Attribute* uval = msg.GetUInt32(STUN_ATTR_LIFETIME); 1343 ASSERT_TRUE(uval != NULL); 1344 EXPECT_EQ(11U, uval->value()); 1345 1346 StunUInt32Attribute* uval2 = StunAttribute::CreateUInt32(STUN_ATTR_LIFETIME); 1347 uval2->SetValue(11); 1348 EXPECT_TRUE(msg2.AddAttribute(uval2)); 1349 1350 bytes = msg.GetByteString(STUN_ATTR_MAGIC_COOKIE); 1351 ASSERT_TRUE(bytes != NULL); 1352 EXPECT_EQ(4U, bytes->length()); 1353 EXPECT_EQ(0, 1354 memcmp(bytes->bytes(), 1355 TURN_MAGIC_COOKIE_VALUE, 1356 sizeof(TURN_MAGIC_COOKIE_VALUE))); 1357 1358 bytes2 = StunAttribute::CreateByteString(STUN_ATTR_MAGIC_COOKIE); 1359 bytes2->CopyBytes(reinterpret_cast<const char*>(TURN_MAGIC_COOKIE_VALUE), 1360 sizeof(TURN_MAGIC_COOKIE_VALUE)); 1361 EXPECT_TRUE(msg2.AddAttribute(bytes2)); 1362 1363 uval = msg.GetUInt32(STUN_ATTR_BANDWIDTH); 1364 ASSERT_TRUE(uval != NULL); 1365 EXPECT_EQ(6U, uval->value()); 1366 1367 uval2 = StunAttribute::CreateUInt32(STUN_ATTR_BANDWIDTH); 1368 uval2->SetValue(6); 1369 EXPECT_TRUE(msg2.AddAttribute(uval2)); 1370 1371 addr = msg.GetAddress(STUN_ATTR_DESTINATION_ADDRESS); 1372 ASSERT_TRUE(addr != NULL); 1373 EXPECT_EQ(1, addr->family()); 1374 EXPECT_EQ(13, addr->port()); 1375 EXPECT_EQ(legacy_ip, addr->ipaddr()); 1376 1377 addr2 = StunAttribute::CreateAddress(STUN_ATTR_DESTINATION_ADDRESS); 1378 addr2->SetPort(13); 1379 addr2->SetIP(legacy_ip); 1380 EXPECT_TRUE(msg2.AddAttribute(addr2)); 1381 1382 addr = msg.GetAddress(STUN_ATTR_SOURCE_ADDRESS2); 1383 ASSERT_TRUE(addr != NULL); 1384 EXPECT_EQ(1, addr->family()); 1385 EXPECT_EQ(13, addr->port()); 1386 EXPECT_EQ(legacy_ip, addr->ipaddr()); 1387 1388 addr2 = StunAttribute::CreateAddress(STUN_ATTR_SOURCE_ADDRESS2); 1389 addr2->SetPort(13); 1390 addr2->SetIP(legacy_ip); 1391 EXPECT_TRUE(msg2.AddAttribute(addr2)); 1392 1393 bytes = msg.GetByteString(STUN_ATTR_DATA); 1394 ASSERT_TRUE(bytes != NULL); 1395 EXPECT_EQ(7U, bytes->length()); 1396 EXPECT_EQ("abcdefg", bytes->GetString()); 1397 1398 bytes2 = StunAttribute::CreateByteString(STUN_ATTR_DATA); 1399 bytes2->CopyBytes("abcdefg"); 1400 EXPECT_TRUE(msg2.AddAttribute(bytes2)); 1401 1402 talk_base::ByteBuffer out; 1403 EXPECT_TRUE(msg.Write(&out)); 1404 EXPECT_EQ(size, out.Length()); 1405 size_t len1 = out.Length(); 1406 std::string outstring; 1407 out.ReadString(&outstring, len1); 1408 EXPECT_EQ(0, memcmp(outstring.c_str(), input, len1)); 1409 1410 talk_base::ByteBuffer out2; 1411 EXPECT_TRUE(msg2.Write(&out2)); 1412 EXPECT_EQ(size, out2.Length()); 1413 size_t len2 = out2.Length(); 1414 std::string outstring2; 1415 out2.ReadString(&outstring2, len2); 1416 EXPECT_EQ(0, memcmp(outstring2.c_str(), input, len2)); 1417 } 1418 1419 } // namespace cricket 1420