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