1 /* 2 * libjingle 3 * Copyright 2004--2005, 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 "talk/p2p/base/stun.h" 29 30 #include <string.h> 31 32 #include "webrtc/base/byteorder.h" 33 #include "webrtc/base/common.h" 34 #include "webrtc/base/crc32.h" 35 #include "webrtc/base/logging.h" 36 #include "webrtc/base/messagedigest.h" 37 #include "webrtc/base/scoped_ptr.h" 38 #include "webrtc/base/stringencode.h" 39 40 using rtc::ByteBuffer; 41 42 namespace cricket { 43 44 const char STUN_ERROR_REASON_TRY_ALTERNATE_SERVER[] = "Try Alternate Server"; 45 const char STUN_ERROR_REASON_BAD_REQUEST[] = "Bad Request"; 46 const char STUN_ERROR_REASON_UNAUTHORIZED[] = "Unauthorized"; 47 const char STUN_ERROR_REASON_FORBIDDEN[] = "Forbidden"; 48 const char STUN_ERROR_REASON_STALE_CREDENTIALS[] = "Stale Credentials"; 49 const char STUN_ERROR_REASON_ALLOCATION_MISMATCH[] = "Allocation Mismatch"; 50 const char STUN_ERROR_REASON_STALE_NONCE[] = "Stale Nonce"; 51 const char STUN_ERROR_REASON_WRONG_CREDENTIALS[] = "Wrong Credentials"; 52 const char STUN_ERROR_REASON_UNSUPPORTED_PROTOCOL[] = "Unsupported Protocol"; 53 const char STUN_ERROR_REASON_ROLE_CONFLICT[] = "Role Conflict"; 54 const char STUN_ERROR_REASON_SERVER_ERROR[] = "Server Error"; 55 56 const char TURN_MAGIC_COOKIE_VALUE[] = { '\x72', '\xC6', '\x4B', '\xC6' }; 57 const char EMPTY_TRANSACTION_ID[] = "0000000000000000"; 58 const uint32 STUN_FINGERPRINT_XOR_VALUE = 0x5354554E; 59 60 // StunMessage 61 62 StunMessage::StunMessage() 63 : type_(0), 64 length_(0), 65 transaction_id_(EMPTY_TRANSACTION_ID) { 66 ASSERT(IsValidTransactionId(transaction_id_)); 67 attrs_ = new std::vector<StunAttribute*>(); 68 } 69 70 StunMessage::~StunMessage() { 71 for (size_t i = 0; i < attrs_->size(); i++) 72 delete (*attrs_)[i]; 73 delete attrs_; 74 } 75 76 bool StunMessage::IsLegacy() const { 77 if (transaction_id_.size() == kStunLegacyTransactionIdLength) 78 return true; 79 ASSERT(transaction_id_.size() == kStunTransactionIdLength); 80 return false; 81 } 82 83 bool StunMessage::SetTransactionID(const std::string& str) { 84 if (!IsValidTransactionId(str)) { 85 return false; 86 } 87 transaction_id_ = str; 88 return true; 89 } 90 91 bool StunMessage::AddAttribute(StunAttribute* attr) { 92 // Fail any attributes that aren't valid for this type of message. 93 if (attr->value_type() != GetAttributeValueType(attr->type())) { 94 return false; 95 } 96 attrs_->push_back(attr); 97 attr->SetOwner(this); 98 size_t attr_length = attr->length(); 99 if (attr_length % 4 != 0) { 100 attr_length += (4 - (attr_length % 4)); 101 } 102 length_ += static_cast<uint16>(attr_length + 4); 103 return true; 104 } 105 106 const StunAddressAttribute* StunMessage::GetAddress(int type) const { 107 switch (type) { 108 case STUN_ATTR_MAPPED_ADDRESS: { 109 // Return XOR-MAPPED-ADDRESS when MAPPED-ADDRESS attribute is 110 // missing. 111 const StunAttribute* mapped_address = 112 GetAttribute(STUN_ATTR_MAPPED_ADDRESS); 113 if (!mapped_address) 114 mapped_address = GetAttribute(STUN_ATTR_XOR_MAPPED_ADDRESS); 115 return reinterpret_cast<const StunAddressAttribute*>(mapped_address); 116 } 117 118 default: 119 return static_cast<const StunAddressAttribute*>(GetAttribute(type)); 120 } 121 } 122 123 const StunUInt32Attribute* StunMessage::GetUInt32(int type) const { 124 return static_cast<const StunUInt32Attribute*>(GetAttribute(type)); 125 } 126 127 const StunUInt64Attribute* StunMessage::GetUInt64(int type) const { 128 return static_cast<const StunUInt64Attribute*>(GetAttribute(type)); 129 } 130 131 const StunByteStringAttribute* StunMessage::GetByteString(int type) const { 132 return static_cast<const StunByteStringAttribute*>(GetAttribute(type)); 133 } 134 135 const StunErrorCodeAttribute* StunMessage::GetErrorCode() const { 136 return static_cast<const StunErrorCodeAttribute*>( 137 GetAttribute(STUN_ATTR_ERROR_CODE)); 138 } 139 140 const StunUInt16ListAttribute* StunMessage::GetUnknownAttributes() const { 141 return static_cast<const StunUInt16ListAttribute*>( 142 GetAttribute(STUN_ATTR_UNKNOWN_ATTRIBUTES)); 143 } 144 145 // Verifies a STUN message has a valid MESSAGE-INTEGRITY attribute, using the 146 // procedure outlined in RFC 5389, section 15.4. 147 bool StunMessage::ValidateMessageIntegrity(const char* data, size_t size, 148 const std::string& password) { 149 // Verifying the size of the message. 150 if ((size % 4) != 0) { 151 return false; 152 } 153 154 // Getting the message length from the STUN header. 155 uint16 msg_length = rtc::GetBE16(&data[2]); 156 if (size != (msg_length + kStunHeaderSize)) { 157 return false; 158 } 159 160 // Finding Message Integrity attribute in stun message. 161 size_t current_pos = kStunHeaderSize; 162 bool has_message_integrity_attr = false; 163 while (current_pos < size) { 164 uint16 attr_type, attr_length; 165 // Getting attribute type and length. 166 attr_type = rtc::GetBE16(&data[current_pos]); 167 attr_length = rtc::GetBE16(&data[current_pos + sizeof(attr_type)]); 168 169 // If M-I, sanity check it, and break out. 170 if (attr_type == STUN_ATTR_MESSAGE_INTEGRITY) { 171 if (attr_length != kStunMessageIntegritySize || 172 current_pos + attr_length > size) { 173 return false; 174 } 175 has_message_integrity_attr = true; 176 break; 177 } 178 179 // Otherwise, skip to the next attribute. 180 current_pos += sizeof(attr_type) + sizeof(attr_length) + attr_length; 181 if ((attr_length % 4) != 0) { 182 current_pos += (4 - (attr_length % 4)); 183 } 184 } 185 186 if (!has_message_integrity_attr) { 187 return false; 188 } 189 190 // Getting length of the message to calculate Message Integrity. 191 size_t mi_pos = current_pos; 192 rtc::scoped_ptr<char[]> temp_data(new char[current_pos]); 193 memcpy(temp_data.get(), data, current_pos); 194 if (size > mi_pos + kStunAttributeHeaderSize + kStunMessageIntegritySize) { 195 // Stun message has other attributes after message integrity. 196 // Adjust the length parameter in stun message to calculate HMAC. 197 size_t extra_offset = size - 198 (mi_pos + kStunAttributeHeaderSize + kStunMessageIntegritySize); 199 size_t new_adjusted_len = size - extra_offset - kStunHeaderSize; 200 201 // Writing new length of the STUN message @ Message Length in temp buffer. 202 // 0 1 2 3 203 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 204 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 205 // |0 0| STUN Message Type | Message Length | 206 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 207 rtc::SetBE16(temp_data.get() + 2, 208 static_cast<uint16>(new_adjusted_len)); 209 } 210 211 char hmac[kStunMessageIntegritySize]; 212 size_t ret = rtc::ComputeHmac(rtc::DIGEST_SHA_1, 213 password.c_str(), password.size(), 214 temp_data.get(), mi_pos, 215 hmac, sizeof(hmac)); 216 ASSERT(ret == sizeof(hmac)); 217 if (ret != sizeof(hmac)) 218 return false; 219 220 // Comparing the calculated HMAC with the one present in the message. 221 return memcmp(data + current_pos + kStunAttributeHeaderSize, 222 hmac, 223 sizeof(hmac)) == 0; 224 } 225 226 bool StunMessage::AddMessageIntegrity(const std::string& password) { 227 return AddMessageIntegrity(password.c_str(), password.size()); 228 } 229 230 bool StunMessage::AddMessageIntegrity(const char* key, 231 size_t keylen) { 232 // Add the attribute with a dummy value. Since this is a known attribute, it 233 // can't fail. 234 StunByteStringAttribute* msg_integrity_attr = 235 new StunByteStringAttribute(STUN_ATTR_MESSAGE_INTEGRITY, 236 std::string(kStunMessageIntegritySize, '0')); 237 VERIFY(AddAttribute(msg_integrity_attr)); 238 239 // Calculate the HMAC for the message. 240 rtc::ByteBuffer buf; 241 if (!Write(&buf)) 242 return false; 243 244 int msg_len_for_hmac = static_cast<int>( 245 buf.Length() - kStunAttributeHeaderSize - msg_integrity_attr->length()); 246 char hmac[kStunMessageIntegritySize]; 247 size_t ret = rtc::ComputeHmac(rtc::DIGEST_SHA_1, 248 key, keylen, 249 buf.Data(), msg_len_for_hmac, 250 hmac, sizeof(hmac)); 251 ASSERT(ret == sizeof(hmac)); 252 if (ret != sizeof(hmac)) { 253 LOG(LS_ERROR) << "HMAC computation failed. Message-Integrity " 254 << "has dummy value."; 255 return false; 256 } 257 258 // Insert correct HMAC into the attribute. 259 msg_integrity_attr->CopyBytes(hmac, sizeof(hmac)); 260 return true; 261 } 262 263 // Verifies a message is in fact a STUN message, by performing the checks 264 // outlined in RFC 5389, section 7.3, including the FINGERPRINT check detailed 265 // in section 15.5. 266 bool StunMessage::ValidateFingerprint(const char* data, size_t size) { 267 // Check the message length. 268 size_t fingerprint_attr_size = 269 kStunAttributeHeaderSize + StunUInt32Attribute::SIZE; 270 if (size % 4 != 0 || size < kStunHeaderSize + fingerprint_attr_size) 271 return false; 272 273 // Skip the rest if the magic cookie isn't present. 274 const char* magic_cookie = 275 data + kStunTransactionIdOffset - kStunMagicCookieLength; 276 if (rtc::GetBE32(magic_cookie) != kStunMagicCookie) 277 return false; 278 279 // Check the fingerprint type and length. 280 const char* fingerprint_attr_data = data + size - fingerprint_attr_size; 281 if (rtc::GetBE16(fingerprint_attr_data) != STUN_ATTR_FINGERPRINT || 282 rtc::GetBE16(fingerprint_attr_data + sizeof(uint16)) != 283 StunUInt32Attribute::SIZE) 284 return false; 285 286 // Check the fingerprint value. 287 uint32 fingerprint = 288 rtc::GetBE32(fingerprint_attr_data + kStunAttributeHeaderSize); 289 return ((fingerprint ^ STUN_FINGERPRINT_XOR_VALUE) == 290 rtc::ComputeCrc32(data, size - fingerprint_attr_size)); 291 } 292 293 bool StunMessage::AddFingerprint() { 294 // Add the attribute with a dummy value. Since this is a known attribute, 295 // it can't fail. 296 StunUInt32Attribute* fingerprint_attr = 297 new StunUInt32Attribute(STUN_ATTR_FINGERPRINT, 0); 298 VERIFY(AddAttribute(fingerprint_attr)); 299 300 // Calculate the CRC-32 for the message and insert it. 301 rtc::ByteBuffer buf; 302 if (!Write(&buf)) 303 return false; 304 305 int msg_len_for_crc32 = static_cast<int>( 306 buf.Length() - kStunAttributeHeaderSize - fingerprint_attr->length()); 307 uint32 c = rtc::ComputeCrc32(buf.Data(), msg_len_for_crc32); 308 309 // Insert the correct CRC-32, XORed with a constant, into the attribute. 310 fingerprint_attr->SetValue(c ^ STUN_FINGERPRINT_XOR_VALUE); 311 return true; 312 } 313 314 bool StunMessage::Read(ByteBuffer* buf) { 315 if (!buf->ReadUInt16(&type_)) 316 return false; 317 318 if (type_ & 0x8000) { 319 // RTP and RTCP set the MSB of first byte, since first two bits are version, 320 // and version is always 2 (10). If set, this is not a STUN packet. 321 return false; 322 } 323 324 if (!buf->ReadUInt16(&length_)) 325 return false; 326 327 std::string magic_cookie; 328 if (!buf->ReadString(&magic_cookie, kStunMagicCookieLength)) 329 return false; 330 331 std::string transaction_id; 332 if (!buf->ReadString(&transaction_id, kStunTransactionIdLength)) 333 return false; 334 335 uint32 magic_cookie_int = 336 *reinterpret_cast<const uint32*>(magic_cookie.data()); 337 if (rtc::NetworkToHost32(magic_cookie_int) != kStunMagicCookie) { 338 // If magic cookie is invalid it means that the peer implements 339 // RFC3489 instead of RFC5389. 340 transaction_id.insert(0, magic_cookie); 341 } 342 ASSERT(IsValidTransactionId(transaction_id)); 343 transaction_id_ = transaction_id; 344 345 if (length_ != buf->Length()) 346 return false; 347 348 attrs_->resize(0); 349 350 size_t rest = buf->Length() - length_; 351 while (buf->Length() > rest) { 352 uint16 attr_type, attr_length; 353 if (!buf->ReadUInt16(&attr_type)) 354 return false; 355 if (!buf->ReadUInt16(&attr_length)) 356 return false; 357 358 StunAttribute* attr = CreateAttribute(attr_type, attr_length); 359 if (!attr) { 360 // Skip any unknown or malformed attributes. 361 if ((attr_length % 4) != 0) { 362 attr_length += (4 - (attr_length % 4)); 363 } 364 if (!buf->Consume(attr_length)) 365 return false; 366 } else { 367 if (!attr->Read(buf)) 368 return false; 369 attrs_->push_back(attr); 370 } 371 } 372 373 ASSERT(buf->Length() == rest); 374 return true; 375 } 376 377 bool StunMessage::Write(ByteBuffer* buf) const { 378 buf->WriteUInt16(type_); 379 buf->WriteUInt16(length_); 380 if (!IsLegacy()) 381 buf->WriteUInt32(kStunMagicCookie); 382 buf->WriteString(transaction_id_); 383 384 for (size_t i = 0; i < attrs_->size(); ++i) { 385 buf->WriteUInt16((*attrs_)[i]->type()); 386 buf->WriteUInt16(static_cast<uint16>((*attrs_)[i]->length())); 387 if (!(*attrs_)[i]->Write(buf)) 388 return false; 389 } 390 391 return true; 392 } 393 394 StunAttributeValueType StunMessage::GetAttributeValueType(int type) const { 395 switch (type) { 396 case STUN_ATTR_MAPPED_ADDRESS: return STUN_VALUE_ADDRESS; 397 case STUN_ATTR_USERNAME: return STUN_VALUE_BYTE_STRING; 398 case STUN_ATTR_MESSAGE_INTEGRITY: return STUN_VALUE_BYTE_STRING; 399 case STUN_ATTR_ERROR_CODE: return STUN_VALUE_ERROR_CODE; 400 case STUN_ATTR_UNKNOWN_ATTRIBUTES: return STUN_VALUE_UINT16_LIST; 401 case STUN_ATTR_REALM: return STUN_VALUE_BYTE_STRING; 402 case STUN_ATTR_NONCE: return STUN_VALUE_BYTE_STRING; 403 case STUN_ATTR_XOR_MAPPED_ADDRESS: return STUN_VALUE_XOR_ADDRESS; 404 case STUN_ATTR_SOFTWARE: return STUN_VALUE_BYTE_STRING; 405 case STUN_ATTR_ALTERNATE_SERVER: return STUN_VALUE_ADDRESS; 406 case STUN_ATTR_FINGERPRINT: return STUN_VALUE_UINT32; 407 case STUN_ATTR_RETRANSMIT_COUNT: return STUN_VALUE_UINT32; 408 default: return STUN_VALUE_UNKNOWN; 409 } 410 } 411 412 StunAttribute* StunMessage::CreateAttribute(int type, size_t length) /*const*/ { 413 StunAttributeValueType value_type = GetAttributeValueType(type); 414 return StunAttribute::Create(value_type, type, 415 static_cast<uint16>(length), this); 416 } 417 418 const StunAttribute* StunMessage::GetAttribute(int type) const { 419 for (size_t i = 0; i < attrs_->size(); ++i) { 420 if ((*attrs_)[i]->type() == type) 421 return (*attrs_)[i]; 422 } 423 return NULL; 424 } 425 426 bool StunMessage::IsValidTransactionId(const std::string& transaction_id) { 427 return transaction_id.size() == kStunTransactionIdLength || 428 transaction_id.size() == kStunLegacyTransactionIdLength; 429 } 430 431 // StunAttribute 432 433 StunAttribute::StunAttribute(uint16 type, uint16 length) 434 : type_(type), length_(length) { 435 } 436 437 void StunAttribute::ConsumePadding(rtc::ByteBuffer* buf) const { 438 int remainder = length_ % 4; 439 if (remainder > 0) { 440 buf->Consume(4 - remainder); 441 } 442 } 443 444 void StunAttribute::WritePadding(rtc::ByteBuffer* buf) const { 445 int remainder = length_ % 4; 446 if (remainder > 0) { 447 char zeroes[4] = {0}; 448 buf->WriteBytes(zeroes, 4 - remainder); 449 } 450 } 451 452 StunAttribute* StunAttribute::Create(StunAttributeValueType value_type, 453 uint16 type, uint16 length, 454 StunMessage* owner) { 455 switch (value_type) { 456 case STUN_VALUE_ADDRESS: 457 return new StunAddressAttribute(type, length); 458 case STUN_VALUE_XOR_ADDRESS: 459 return new StunXorAddressAttribute(type, length, owner); 460 case STUN_VALUE_UINT32: 461 return new StunUInt32Attribute(type); 462 case STUN_VALUE_UINT64: 463 return new StunUInt64Attribute(type); 464 case STUN_VALUE_BYTE_STRING: 465 return new StunByteStringAttribute(type, length); 466 case STUN_VALUE_ERROR_CODE: 467 return new StunErrorCodeAttribute(type, length); 468 case STUN_VALUE_UINT16_LIST: 469 return new StunUInt16ListAttribute(type, length); 470 default: 471 return NULL; 472 } 473 } 474 475 StunAddressAttribute* StunAttribute::CreateAddress(uint16 type) { 476 return new StunAddressAttribute(type, 0); 477 } 478 479 StunXorAddressAttribute* StunAttribute::CreateXorAddress(uint16 type) { 480 return new StunXorAddressAttribute(type, 0, NULL); 481 } 482 483 StunUInt64Attribute* StunAttribute::CreateUInt64(uint16 type) { 484 return new StunUInt64Attribute(type); 485 } 486 487 StunUInt32Attribute* StunAttribute::CreateUInt32(uint16 type) { 488 return new StunUInt32Attribute(type); 489 } 490 491 StunByteStringAttribute* StunAttribute::CreateByteString(uint16 type) { 492 return new StunByteStringAttribute(type, 0); 493 } 494 495 StunErrorCodeAttribute* StunAttribute::CreateErrorCode() { 496 return new StunErrorCodeAttribute( 497 STUN_ATTR_ERROR_CODE, StunErrorCodeAttribute::MIN_SIZE); 498 } 499 500 StunUInt16ListAttribute* StunAttribute::CreateUnknownAttributes() { 501 return new StunUInt16ListAttribute(STUN_ATTR_UNKNOWN_ATTRIBUTES, 0); 502 } 503 504 StunAddressAttribute::StunAddressAttribute(uint16 type, 505 const rtc::SocketAddress& addr) 506 : StunAttribute(type, 0) { 507 SetAddress(addr); 508 } 509 510 StunAddressAttribute::StunAddressAttribute(uint16 type, uint16 length) 511 : StunAttribute(type, length) { 512 } 513 514 bool StunAddressAttribute::Read(ByteBuffer* buf) { 515 uint8 dummy; 516 if (!buf->ReadUInt8(&dummy)) 517 return false; 518 519 uint8 stun_family; 520 if (!buf->ReadUInt8(&stun_family)) { 521 return false; 522 } 523 uint16 port; 524 if (!buf->ReadUInt16(&port)) 525 return false; 526 if (stun_family == STUN_ADDRESS_IPV4) { 527 in_addr v4addr; 528 if (length() != SIZE_IP4) { 529 return false; 530 } 531 if (!buf->ReadBytes(reinterpret_cast<char*>(&v4addr), sizeof(v4addr))) { 532 return false; 533 } 534 rtc::IPAddress ipaddr(v4addr); 535 SetAddress(rtc::SocketAddress(ipaddr, port)); 536 } else if (stun_family == STUN_ADDRESS_IPV6) { 537 in6_addr v6addr; 538 if (length() != SIZE_IP6) { 539 return false; 540 } 541 if (!buf->ReadBytes(reinterpret_cast<char*>(&v6addr), sizeof(v6addr))) { 542 return false; 543 } 544 rtc::IPAddress ipaddr(v6addr); 545 SetAddress(rtc::SocketAddress(ipaddr, port)); 546 } else { 547 return false; 548 } 549 return true; 550 } 551 552 bool StunAddressAttribute::Write(ByteBuffer* buf) const { 553 StunAddressFamily address_family = family(); 554 if (address_family == STUN_ADDRESS_UNDEF) { 555 LOG(LS_ERROR) << "Error writing address attribute: unknown family."; 556 return false; 557 } 558 buf->WriteUInt8(0); 559 buf->WriteUInt8(address_family); 560 buf->WriteUInt16(address_.port()); 561 switch (address_.family()) { 562 case AF_INET: { 563 in_addr v4addr = address_.ipaddr().ipv4_address(); 564 buf->WriteBytes(reinterpret_cast<char*>(&v4addr), sizeof(v4addr)); 565 break; 566 } 567 case AF_INET6: { 568 in6_addr v6addr = address_.ipaddr().ipv6_address(); 569 buf->WriteBytes(reinterpret_cast<char*>(&v6addr), sizeof(v6addr)); 570 break; 571 } 572 } 573 return true; 574 } 575 576 StunXorAddressAttribute::StunXorAddressAttribute(uint16 type, 577 const rtc::SocketAddress& addr) 578 : StunAddressAttribute(type, addr), owner_(NULL) { 579 } 580 581 StunXorAddressAttribute::StunXorAddressAttribute(uint16 type, 582 uint16 length, 583 StunMessage* owner) 584 : StunAddressAttribute(type, length), owner_(owner) {} 585 586 rtc::IPAddress StunXorAddressAttribute::GetXoredIP() const { 587 if (owner_) { 588 rtc::IPAddress ip = ipaddr(); 589 switch (ip.family()) { 590 case AF_INET: { 591 in_addr v4addr = ip.ipv4_address(); 592 v4addr.s_addr = 593 (v4addr.s_addr ^ rtc::HostToNetwork32(kStunMagicCookie)); 594 return rtc::IPAddress(v4addr); 595 } 596 case AF_INET6: { 597 in6_addr v6addr = ip.ipv6_address(); 598 const std::string& transaction_id = owner_->transaction_id(); 599 if (transaction_id.length() == kStunTransactionIdLength) { 600 uint32 transactionid_as_ints[3]; 601 memcpy(&transactionid_as_ints[0], transaction_id.c_str(), 602 transaction_id.length()); 603 uint32* ip_as_ints = reinterpret_cast<uint32*>(&v6addr.s6_addr); 604 // Transaction ID is in network byte order, but magic cookie 605 // is stored in host byte order. 606 ip_as_ints[0] = 607 (ip_as_ints[0] ^ rtc::HostToNetwork32(kStunMagicCookie)); 608 ip_as_ints[1] = (ip_as_ints[1] ^ transactionid_as_ints[0]); 609 ip_as_ints[2] = (ip_as_ints[2] ^ transactionid_as_ints[1]); 610 ip_as_ints[3] = (ip_as_ints[3] ^ transactionid_as_ints[2]); 611 return rtc::IPAddress(v6addr); 612 } 613 break; 614 } 615 } 616 } 617 // Invalid ip family or transaction ID, or missing owner. 618 // Return an AF_UNSPEC address. 619 return rtc::IPAddress(); 620 } 621 622 bool StunXorAddressAttribute::Read(ByteBuffer* buf) { 623 if (!StunAddressAttribute::Read(buf)) 624 return false; 625 uint16 xoredport = port() ^ (kStunMagicCookie >> 16); 626 rtc::IPAddress xored_ip = GetXoredIP(); 627 SetAddress(rtc::SocketAddress(xored_ip, xoredport)); 628 return true; 629 } 630 631 bool StunXorAddressAttribute::Write(ByteBuffer* buf) const { 632 StunAddressFamily address_family = family(); 633 if (address_family == STUN_ADDRESS_UNDEF) { 634 LOG(LS_ERROR) << "Error writing xor-address attribute: unknown family."; 635 return false; 636 } 637 rtc::IPAddress xored_ip = GetXoredIP(); 638 if (xored_ip.family() == AF_UNSPEC) { 639 return false; 640 } 641 buf->WriteUInt8(0); 642 buf->WriteUInt8(family()); 643 buf->WriteUInt16(port() ^ (kStunMagicCookie >> 16)); 644 switch (xored_ip.family()) { 645 case AF_INET: { 646 in_addr v4addr = xored_ip.ipv4_address(); 647 buf->WriteBytes(reinterpret_cast<const char*>(&v4addr), sizeof(v4addr)); 648 break; 649 } 650 case AF_INET6: { 651 in6_addr v6addr = xored_ip.ipv6_address(); 652 buf->WriteBytes(reinterpret_cast<const char*>(&v6addr), sizeof(v6addr)); 653 break; 654 } 655 } 656 return true; 657 } 658 659 StunUInt32Attribute::StunUInt32Attribute(uint16 type, uint32 value) 660 : StunAttribute(type, SIZE), bits_(value) { 661 } 662 663 StunUInt32Attribute::StunUInt32Attribute(uint16 type) 664 : StunAttribute(type, SIZE), bits_(0) { 665 } 666 667 bool StunUInt32Attribute::GetBit(size_t index) const { 668 ASSERT(index < 32); 669 return static_cast<bool>((bits_ >> index) & 0x1); 670 } 671 672 void StunUInt32Attribute::SetBit(size_t index, bool value) { 673 ASSERT(index < 32); 674 bits_ &= ~(1 << index); 675 bits_ |= value ? (1 << index) : 0; 676 } 677 678 bool StunUInt32Attribute::Read(ByteBuffer* buf) { 679 if (length() != SIZE || !buf->ReadUInt32(&bits_)) 680 return false; 681 return true; 682 } 683 684 bool StunUInt32Attribute::Write(ByteBuffer* buf) const { 685 buf->WriteUInt32(bits_); 686 return true; 687 } 688 689 StunUInt64Attribute::StunUInt64Attribute(uint16 type, uint64 value) 690 : StunAttribute(type, SIZE), bits_(value) { 691 } 692 693 StunUInt64Attribute::StunUInt64Attribute(uint16 type) 694 : StunAttribute(type, SIZE), bits_(0) { 695 } 696 697 bool StunUInt64Attribute::Read(ByteBuffer* buf) { 698 if (length() != SIZE || !buf->ReadUInt64(&bits_)) 699 return false; 700 return true; 701 } 702 703 bool StunUInt64Attribute::Write(ByteBuffer* buf) const { 704 buf->WriteUInt64(bits_); 705 return true; 706 } 707 708 StunByteStringAttribute::StunByteStringAttribute(uint16 type) 709 : StunAttribute(type, 0), bytes_(NULL) { 710 } 711 712 StunByteStringAttribute::StunByteStringAttribute(uint16 type, 713 const std::string& str) 714 : StunAttribute(type, 0), bytes_(NULL) { 715 CopyBytes(str.c_str(), str.size()); 716 } 717 718 StunByteStringAttribute::StunByteStringAttribute(uint16 type, 719 const void* bytes, 720 size_t length) 721 : StunAttribute(type, 0), bytes_(NULL) { 722 CopyBytes(bytes, length); 723 } 724 725 StunByteStringAttribute::StunByteStringAttribute(uint16 type, uint16 length) 726 : StunAttribute(type, length), bytes_(NULL) { 727 } 728 729 StunByteStringAttribute::~StunByteStringAttribute() { 730 delete [] bytes_; 731 } 732 733 void StunByteStringAttribute::CopyBytes(const char* bytes) { 734 CopyBytes(bytes, strlen(bytes)); 735 } 736 737 void StunByteStringAttribute::CopyBytes(const void* bytes, size_t length) { 738 char* new_bytes = new char[length]; 739 memcpy(new_bytes, bytes, length); 740 SetBytes(new_bytes, length); 741 } 742 743 uint8 StunByteStringAttribute::GetByte(size_t index) const { 744 ASSERT(bytes_ != NULL); 745 ASSERT(index < length()); 746 return static_cast<uint8>(bytes_[index]); 747 } 748 749 void StunByteStringAttribute::SetByte(size_t index, uint8 value) { 750 ASSERT(bytes_ != NULL); 751 ASSERT(index < length()); 752 bytes_[index] = value; 753 } 754 755 bool StunByteStringAttribute::Read(ByteBuffer* buf) { 756 bytes_ = new char[length()]; 757 if (!buf->ReadBytes(bytes_, length())) { 758 return false; 759 } 760 761 ConsumePadding(buf); 762 return true; 763 } 764 765 bool StunByteStringAttribute::Write(ByteBuffer* buf) const { 766 buf->WriteBytes(bytes_, length()); 767 WritePadding(buf); 768 return true; 769 } 770 771 void StunByteStringAttribute::SetBytes(char* bytes, size_t length) { 772 delete [] bytes_; 773 bytes_ = bytes; 774 SetLength(static_cast<uint16>(length)); 775 } 776 777 StunErrorCodeAttribute::StunErrorCodeAttribute(uint16 type, int code, 778 const std::string& reason) 779 : StunAttribute(type, 0) { 780 SetCode(code); 781 SetReason(reason); 782 } 783 784 StunErrorCodeAttribute::StunErrorCodeAttribute(uint16 type, uint16 length) 785 : StunAttribute(type, length), class_(0), number_(0) { 786 } 787 788 StunErrorCodeAttribute::~StunErrorCodeAttribute() { 789 } 790 791 int StunErrorCodeAttribute::code() const { 792 return class_ * 100 + number_; 793 } 794 795 void StunErrorCodeAttribute::SetCode(int code) { 796 class_ = static_cast<uint8>(code / 100); 797 number_ = static_cast<uint8>(code % 100); 798 } 799 800 void StunErrorCodeAttribute::SetReason(const std::string& reason) { 801 SetLength(MIN_SIZE + static_cast<uint16>(reason.size())); 802 reason_ = reason; 803 } 804 805 bool StunErrorCodeAttribute::Read(ByteBuffer* buf) { 806 uint32 val; 807 if (length() < MIN_SIZE || !buf->ReadUInt32(&val)) 808 return false; 809 810 if ((val >> 11) != 0) 811 LOG(LS_ERROR) << "error-code bits not zero"; 812 813 class_ = ((val >> 8) & 0x7); 814 number_ = (val & 0xff); 815 816 if (!buf->ReadString(&reason_, length() - 4)) 817 return false; 818 819 ConsumePadding(buf); 820 return true; 821 } 822 823 bool StunErrorCodeAttribute::Write(ByteBuffer* buf) const { 824 buf->WriteUInt32(class_ << 8 | number_); 825 buf->WriteString(reason_); 826 WritePadding(buf); 827 return true; 828 } 829 830 StunUInt16ListAttribute::StunUInt16ListAttribute(uint16 type, uint16 length) 831 : StunAttribute(type, length) { 832 attr_types_ = new std::vector<uint16>(); 833 } 834 835 StunUInt16ListAttribute::~StunUInt16ListAttribute() { 836 delete attr_types_; 837 } 838 839 size_t StunUInt16ListAttribute::Size() const { 840 return attr_types_->size(); 841 } 842 843 uint16 StunUInt16ListAttribute::GetType(int index) const { 844 return (*attr_types_)[index]; 845 } 846 847 void StunUInt16ListAttribute::SetType(int index, uint16 value) { 848 (*attr_types_)[index] = value; 849 } 850 851 void StunUInt16ListAttribute::AddType(uint16 value) { 852 attr_types_->push_back(value); 853 SetLength(static_cast<uint16>(attr_types_->size() * 2)); 854 } 855 856 bool StunUInt16ListAttribute::Read(ByteBuffer* buf) { 857 if (length() % 2) 858 return false; 859 860 for (size_t i = 0; i < length() / 2; i++) { 861 uint16 attr; 862 if (!buf->ReadUInt16(&attr)) 863 return false; 864 attr_types_->push_back(attr); 865 } 866 // Padding of these attributes is done in RFC 5389 style. This is 867 // slightly different from RFC3489, but it shouldn't be important. 868 // RFC3489 pads out to a 32 bit boundary by duplicating one of the 869 // entries in the list (not necessarily the last one - it's unspecified). 870 // RFC5389 pads on the end, and the bytes are always ignored. 871 ConsumePadding(buf); 872 return true; 873 } 874 875 bool StunUInt16ListAttribute::Write(ByteBuffer* buf) const { 876 for (size_t i = 0; i < attr_types_->size(); ++i) { 877 buf->WriteUInt16((*attr_types_)[i]); 878 } 879 WritePadding(buf); 880 return true; 881 } 882 883 int GetStunSuccessResponseType(int req_type) { 884 return IsStunRequestType(req_type) ? (req_type | 0x100) : -1; 885 } 886 887 int GetStunErrorResponseType(int req_type) { 888 return IsStunRequestType(req_type) ? (req_type | 0x110) : -1; 889 } 890 891 bool IsStunRequestType(int msg_type) { 892 return ((msg_type & kStunTypeMask) == 0x000); 893 } 894 895 bool IsStunIndicationType(int msg_type) { 896 return ((msg_type & kStunTypeMask) == 0x010); 897 } 898 899 bool IsStunSuccessResponseType(int msg_type) { 900 return ((msg_type & kStunTypeMask) == 0x100); 901 } 902 903 bool IsStunErrorResponseType(int msg_type) { 904 return ((msg_type & kStunTypeMask) == 0x110); 905 } 906 907 bool ComputeStunCredentialHash(const std::string& username, 908 const std::string& realm, 909 const std::string& password, 910 std::string* hash) { 911 // http://tools.ietf.org/html/rfc5389#section-15.4 912 // long-term credentials will be calculated using the key and key is 913 // key = MD5(username ":" realm ":" SASLprep(password)) 914 std::string input = username; 915 input += ':'; 916 input += realm; 917 input += ':'; 918 input += password; 919 920 char digest[rtc::MessageDigest::kMaxSize]; 921 size_t size = rtc::ComputeDigest( 922 rtc::DIGEST_MD5, input.c_str(), input.size(), 923 digest, sizeof(digest)); 924 if (size == 0) { 925 return false; 926 } 927 928 *hash = std::string(digest, size); 929 return true; 930 } 931 932 } // namespace cricket 933