stun.cc (49082B)
1 /* 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "api/transport/stun.h" 12 13 #include <algorithm> // IWYU pragma: keep 14 #include <cstdint> 15 #include <cstring> 16 #include <functional> 17 #include <iterator> 18 #include <memory> 19 #include <optional> 20 #include <string> 21 #include <utility> 22 #include <vector> 23 24 #include "absl/strings/string_view.h" 25 #include "api/array_view.h" 26 #include "rtc_base/byte_buffer.h" 27 #include "rtc_base/byte_order.h" 28 #include "rtc_base/checks.h" 29 #include "rtc_base/crc32.h" 30 #include "rtc_base/crypto_random.h" 31 #include "rtc_base/ip_address.h" 32 #include "rtc_base/logging.h" 33 #include "rtc_base/message_digest.h" 34 #include "rtc_base/net_helpers.h" 35 #include "rtc_base/socket_address.h" 36 #include "system_wrappers/include/metrics.h" 37 38 using ::webrtc::ByteBufferReader; 39 using ::webrtc::ByteBufferWriter; 40 41 namespace webrtc { 42 43 namespace { 44 45 const int k127Utf8CharactersLengthInBytes = 508; 46 const int kMessageIntegrityAttributeLength = 20; 47 const int kTheoreticalMaximumAttributeLength = 65535; 48 49 uint32_t ReduceTransactionId(absl::string_view transaction_id) { 50 RTC_DCHECK(transaction_id.length() == kStunTransactionIdLength || 51 transaction_id.length() == kStunLegacyTransactionIdLength) 52 << transaction_id.length(); 53 ByteBufferReader reader( 54 MakeArrayView(reinterpret_cast<const uint8_t*>(transaction_id.data()), 55 transaction_id.size())); 56 uint32_t result = 0; 57 uint32_t next; 58 while (reader.ReadUInt32(&next)) { 59 result ^= next; 60 } 61 return result; 62 } 63 64 // Check the maximum length of a BYTE_STRING attribute against specifications. 65 bool LengthValid(int type, int length) { 66 // "Less than 509 bytes" is intended to indicate a maximum of 127 67 // UTF-8 characters, which may take up to 4 bytes per character. 68 switch (type) { 69 case STUN_ATTR_USERNAME: 70 return length <= 71 k127Utf8CharactersLengthInBytes; // RFC 8489 section 14.3 72 case STUN_ATTR_MESSAGE_INTEGRITY: 73 return length == 74 kMessageIntegrityAttributeLength; // RFC 8489 section 14.5 75 case STUN_ATTR_REALM: 76 return length <= 77 k127Utf8CharactersLengthInBytes; // RFC 8489 section 14.9 78 case STUN_ATTR_NONCE: 79 return length <= 80 k127Utf8CharactersLengthInBytes; // RFC 8489 section 14.10 81 case STUN_ATTR_SOFTWARE: 82 return length <= 83 k127Utf8CharactersLengthInBytes; // RFC 8489 section 14.14 84 case STUN_ATTR_DATA: 85 // No length restriction in RFC; it's the content of an UDP datagram, 86 // which in theory can be up to 65.535 bytes. 87 // TODO(bugs.webrtc.org/12179): Write a test to find the real limit. 88 return length <= kTheoreticalMaximumAttributeLength; 89 default: 90 // Return an arbitrary restriction for all other types. 91 return length <= kTheoreticalMaximumAttributeLength; 92 } 93 RTC_DCHECK_NOTREACHED(); 94 return true; 95 } 96 97 } // namespace 98 99 const char STUN_ERROR_REASON_TRY_ALTERNATE_SERVER[] = "Try Alternate Server"; 100 const char STUN_ERROR_REASON_BAD_REQUEST[] = "Bad Request"; 101 const char STUN_ERROR_REASON_UNAUTHORIZED[] = "Unauthorized"; 102 const char STUN_ERROR_REASON_UNKNOWN_ATTRIBUTE[] = "Unknown Attribute"; 103 const char STUN_ERROR_REASON_FORBIDDEN[] = "Forbidden"; 104 const char STUN_ERROR_REASON_ALLOCATION_MISMATCH[] = "Allocation Mismatch"; 105 const char STUN_ERROR_REASON_STALE_NONCE[] = "Stale Nonce"; 106 const char STUN_ERROR_REASON_WRONG_CREDENTIALS[] = "Wrong Credentials"; 107 const char STUN_ERROR_REASON_UNSUPPORTED_PROTOCOL[] = "Unsupported Protocol"; 108 const char STUN_ERROR_REASON_ROLE_CONFLICT[] = "Role Conflict"; 109 const char STUN_ERROR_REASON_SERVER_ERROR[] = "Server Error"; 110 111 const char EMPTY_TRANSACTION_ID[] = "0000000000000000"; 112 const uint32_t STUN_FINGERPRINT_XOR_VALUE = 0x5354554E; 113 const int SERVER_NOT_REACHABLE_ERROR = 701; 114 115 // StunMessage 116 117 StunMessage::StunMessage() 118 : StunMessage(STUN_INVALID_MESSAGE_TYPE, EMPTY_TRANSACTION_ID) {} 119 120 StunMessage::StunMessage(uint16_t type) 121 : StunMessage(type, GenerateTransactionId()) {} 122 123 StunMessage::StunMessage(uint16_t type, absl::string_view transaction_id) 124 : type_(type), 125 transaction_id_(transaction_id), 126 reduced_transaction_id_(ReduceTransactionId(transaction_id_)) { 127 RTC_DCHECK(IsValidTransactionId(transaction_id_)); 128 } 129 130 StunMessage::~StunMessage() = default; 131 132 bool StunMessage::IsLegacy() const { 133 if (transaction_id_.size() == kStunLegacyTransactionIdLength) 134 return true; 135 RTC_DCHECK(transaction_id_.size() == kStunTransactionIdLength); 136 return false; 137 } 138 139 static bool DesignatedExpertRange(int attr_type) { 140 return (attr_type >= 0x4000 && attr_type <= 0x7FFF) || 141 (attr_type >= 0xC000 && attr_type <= 0xFFFF); 142 } 143 144 void StunMessage::AddAttribute(std::unique_ptr<StunAttribute> attr) { 145 // Fail any attributes that aren't valid for this type of message, 146 // but allow any type for the range that in the RFC is reserved for 147 // the "designated experts". 148 if (!DesignatedExpertRange(attr->type())) { 149 RTC_DCHECK_EQ(attr->value_type(), GetAttributeValueType(attr->type())); 150 } 151 152 attr->SetOwner(this); 153 size_t attr_length = attr->length(); 154 if (attr_length % 4 != 0) { 155 attr_length += (4 - (attr_length % 4)); 156 } 157 length_ += static_cast<uint16_t>(attr_length + 4); 158 159 attrs_.push_back(std::move(attr)); 160 } 161 162 std::unique_ptr<StunAttribute> StunMessage::RemoveAttribute(int type) { 163 std::unique_ptr<StunAttribute> attribute; 164 for (auto it = attrs_.rbegin(); it != attrs_.rend(); ++it) { 165 if ((*it)->type() == type) { 166 attribute = std::move(*it); 167 attrs_.erase(std::next(it).base()); 168 break; 169 } 170 } 171 if (attribute) { 172 attribute->SetOwner(nullptr); 173 size_t attr_length = attribute->length(); 174 if (attr_length % 4 != 0) { 175 attr_length += (4 - (attr_length % 4)); 176 } 177 length_ -= static_cast<uint16_t>(attr_length + 4); 178 } 179 return attribute; 180 } 181 182 void StunMessage::ClearAttributes() { 183 for (auto it = attrs_.rbegin(); it != attrs_.rend(); ++it) { 184 (*it)->SetOwner(nullptr); 185 } 186 attrs_.clear(); 187 length_ = 0; 188 } 189 190 std::vector<uint16_t> StunMessage::GetNonComprehendedAttributes() const { 191 std::vector<uint16_t> unknown_attributes; 192 for (auto& attr : attrs_) { 193 // "comprehension-required" range is 0x0000-0x7FFF. 194 if (attr->type() >= 0x0000 && attr->type() <= 0x7FFF && 195 GetAttributeValueType(attr->type()) == STUN_VALUE_UNKNOWN) { 196 unknown_attributes.push_back(attr->type()); 197 } 198 } 199 return unknown_attributes; 200 } 201 202 const StunAddressAttribute* StunMessage::GetAddress(int type) const { 203 switch (type) { 204 case STUN_ATTR_MAPPED_ADDRESS: { 205 // Return XOR-MAPPED-ADDRESS when MAPPED-ADDRESS attribute is 206 // missing. 207 const StunAttribute* mapped_address = 208 GetAttribute(STUN_ATTR_MAPPED_ADDRESS); 209 if (!mapped_address) 210 mapped_address = GetAttribute(STUN_ATTR_XOR_MAPPED_ADDRESS); 211 return reinterpret_cast<const StunAddressAttribute*>(mapped_address); 212 } 213 214 default: 215 return static_cast<const StunAddressAttribute*>(GetAttribute(type)); 216 } 217 } 218 219 const StunUInt32Attribute* StunMessage::GetUInt32(int type) const { 220 return static_cast<const StunUInt32Attribute*>(GetAttribute(type)); 221 } 222 223 const StunUInt64Attribute* StunMessage::GetUInt64(int type) const { 224 return static_cast<const StunUInt64Attribute*>(GetAttribute(type)); 225 } 226 227 const StunByteStringAttribute* StunMessage::GetByteString(int type) const { 228 return static_cast<const StunByteStringAttribute*>(GetAttribute(type)); 229 } 230 231 const StunUInt16ListAttribute* StunMessage::GetUInt16List(int type) const { 232 return static_cast<const StunUInt16ListAttribute*>(GetAttribute(type)); 233 } 234 235 const StunErrorCodeAttribute* StunMessage::GetErrorCode() const { 236 return static_cast<const StunErrorCodeAttribute*>( 237 GetAttribute(STUN_ATTR_ERROR_CODE)); 238 } 239 240 int StunMessage::GetErrorCodeValue() const { 241 const StunErrorCodeAttribute* error_attribute = GetErrorCode(); 242 return error_attribute ? error_attribute->code() : STUN_ERROR_GLOBAL_FAILURE; 243 } 244 245 const StunUInt16ListAttribute* StunMessage::GetUnknownAttributes() const { 246 return static_cast<const StunUInt16ListAttribute*>( 247 GetAttribute(STUN_ATTR_UNKNOWN_ATTRIBUTES)); 248 } 249 250 StunMessage::IntegrityStatus StunMessage::ValidateMessageIntegrity( 251 const std::string& password) { 252 RTC_DCHECK(integrity_ == IntegrityStatus::kNotSet) 253 << "Usage error: Verification should only be done once"; 254 password_ = password; 255 if (GetByteString(STUN_ATTR_MESSAGE_INTEGRITY)) { 256 if (ValidateMessageIntegrityOfType( 257 STUN_ATTR_MESSAGE_INTEGRITY, kStunMessageIntegritySize, 258 buffer_.c_str(), buffer_.size(), password)) { 259 integrity_ = IntegrityStatus::kIntegrityOk; 260 } else { 261 integrity_ = IntegrityStatus::kIntegrityBad; 262 } 263 } else if (GetByteString(STUN_ATTR_GOOG_MESSAGE_INTEGRITY_32)) { 264 if (ValidateMessageIntegrityOfType( 265 STUN_ATTR_GOOG_MESSAGE_INTEGRITY_32, kStunMessageIntegrity32Size, 266 buffer_.c_str(), buffer_.size(), password)) { 267 integrity_ = IntegrityStatus::kIntegrityOk; 268 } else { 269 integrity_ = IntegrityStatus::kIntegrityBad; 270 } 271 } else { 272 integrity_ = IntegrityStatus::kNoIntegrity; 273 } 274 // Log the result of integrity checking. See crbug.com/1177125 for background. 275 // Convert args to integer for the benefit of the macros. 276 int bucket_count = static_cast<int>(IntegrityStatus::kMaxValue) + 1; 277 int integrity = static_cast<int>(integrity_); 278 if (IsStunRequestType(type_)) { 279 RTC_HISTOGRAM_ENUMERATION("WebRTC.Stun.Integrity.Request", integrity, 280 bucket_count); 281 } else if (IsStunSuccessResponseType(type_)) { 282 RTC_HISTOGRAM_ENUMERATION("WebRTC.Stun.Integrity.Response", integrity, 283 bucket_count); 284 } else if (IsStunIndicationType(type_)) { 285 RTC_HISTOGRAM_ENUMERATION("WebRTC.Stun.Integrity.Indication", integrity, 286 bucket_count); 287 } else { 288 RTC_DCHECK(IsStunErrorResponseType(type_)); 289 auto* error_attribute = GetErrorCode(); 290 if (!error_attribute) { 291 RTC_HISTOGRAM_ENUMERATION( 292 "WebRTC.Stun.Integrity.ErrorResponse.NoErrorAttribute", integrity, 293 bucket_count); 294 } else { 295 switch (error_attribute->code()) { 296 case STUN_ERROR_TRY_ALTERNATE: 297 RTC_HISTOGRAM_ENUMERATION( 298 "WebRTC.Stun.Integrity.ErrorResponse.TryAlternate", integrity, 299 bucket_count); 300 break; 301 case STUN_ERROR_BAD_REQUEST: 302 RTC_HISTOGRAM_ENUMERATION( 303 "WebRTC.Stun.Integrity.ErrorResponse.BadRequest", integrity, 304 bucket_count); 305 break; 306 case STUN_ERROR_UNAUTHORIZED: 307 RTC_HISTOGRAM_ENUMERATION( 308 "WebRTC.Stun.Integrity.ErrorResponse.Unauthorized", integrity, 309 bucket_count); 310 break; 311 case STUN_ERROR_UNKNOWN_ATTRIBUTE: 312 RTC_HISTOGRAM_ENUMERATION( 313 "WebRTC.Stun.Integrity.ErrorResponse.UnknownAttribute", integrity, 314 bucket_count); 315 break; 316 case STUN_ERROR_STALE_NONCE: 317 RTC_HISTOGRAM_ENUMERATION( 318 "WebRTC.Stun.Integrity.ErrorResponse.StaleNonce", integrity, 319 bucket_count); 320 break; 321 case STUN_ERROR_SERVER_ERROR: 322 RTC_HISTOGRAM_ENUMERATION( 323 "WebRTC.Stun.Integrity.ErrorResponse.ServerError", integrity, 324 bucket_count); 325 break; 326 case STUN_ERROR_GLOBAL_FAILURE: 327 RTC_HISTOGRAM_ENUMERATION( 328 "WebRTC.Stun.Integrity.ErrorResponse.GlobalFailure", integrity, 329 bucket_count); 330 break; 331 default: 332 RTC_HISTOGRAM_ENUMERATION( 333 "WebRTC.Stun.Integrity.ErrorResponse.ErrorOther", integrity, 334 bucket_count); 335 break; 336 } 337 } 338 } 339 return integrity_; 340 } 341 342 StunMessage::IntegrityStatus StunMessage::RevalidateMessageIntegrity( 343 const std::string& password) { 344 RTC_LOG(LS_INFO) << "Message revalidation, old status was " 345 << static_cast<int>(integrity_); 346 integrity_ = IntegrityStatus::kNotSet; 347 return ValidateMessageIntegrity(password); 348 } 349 350 bool StunMessage::ValidateMessageIntegrityForTesting( 351 const char* data, 352 size_t size, 353 const std::string& password) { 354 return ValidateMessageIntegrityOfType(STUN_ATTR_MESSAGE_INTEGRITY, 355 kStunMessageIntegritySize, data, size, 356 password); 357 } 358 359 bool StunMessage::ValidateMessageIntegrity32ForTesting( 360 const char* data, 361 size_t size, 362 const std::string& password) { 363 return ValidateMessageIntegrityOfType(STUN_ATTR_GOOG_MESSAGE_INTEGRITY_32, 364 kStunMessageIntegrity32Size, data, size, 365 password); 366 } 367 368 // Verifies a STUN message has a valid MESSAGE-INTEGRITY attribute, using the 369 // procedure outlined in RFC 5389, section 15.4. 370 bool StunMessage::ValidateMessageIntegrityOfType(int mi_attr_type, 371 size_t mi_attr_size, 372 const char* data, 373 size_t size, 374 const std::string& password) { 375 RTC_DCHECK(mi_attr_size <= kStunMessageIntegritySize); 376 377 // Verifying the size of the message. 378 if ((size % 4) != 0 || size < kStunHeaderSize) { 379 return false; 380 } 381 382 // Getting the message length from the STUN header. 383 uint16_t msg_length = GetBE16(&data[2]); 384 if (size != (msg_length + kStunHeaderSize)) { 385 return false; 386 } 387 388 // Finding Message Integrity attribute in stun message. 389 size_t current_pos = kStunHeaderSize; 390 bool has_message_integrity_attr = false; 391 while (current_pos + 4 <= size) { 392 uint16_t attr_type, attr_length; 393 // Getting attribute type and length. 394 attr_type = GetBE16(&data[current_pos]); 395 attr_length = GetBE16(&data[current_pos + sizeof(attr_type)]); 396 397 // If M-I, sanity check it, and break out. 398 if (attr_type == mi_attr_type) { 399 if (attr_length != mi_attr_size || 400 current_pos + sizeof(attr_type) + sizeof(attr_length) + attr_length > 401 size) { 402 return false; 403 } 404 has_message_integrity_attr = true; 405 break; 406 } 407 408 // Otherwise, skip to the next attribute. 409 current_pos += sizeof(attr_type) + sizeof(attr_length) + attr_length; 410 if ((attr_length % 4) != 0) { 411 current_pos += (4 - (attr_length % 4)); 412 } 413 } 414 415 if (!has_message_integrity_attr) { 416 return false; 417 } 418 419 // Getting length of the message to calculate Message Integrity. 420 size_t mi_pos = current_pos; 421 std::unique_ptr<char[]> temp_data(new char[current_pos]); 422 memcpy(temp_data.get(), data, current_pos); 423 if (size > mi_pos + kStunAttributeHeaderSize + mi_attr_size) { 424 // Stun message has other attributes after message integrity. 425 // Adjust the length parameter in stun message to calculate HMAC. 426 size_t extra_offset = 427 size - (mi_pos + kStunAttributeHeaderSize + mi_attr_size); 428 size_t new_adjusted_len = size - extra_offset - kStunHeaderSize; 429 430 // Writing new length of the STUN message @ Message Length in temp buffer. 431 // 0 1 2 3 432 // 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 433 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 434 // |0 0| STUN Message Type | Message Length | 435 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 436 SetBE16(temp_data.get() + 2, static_cast<uint16_t>(new_adjusted_len)); 437 } 438 439 char hmac[kStunMessageIntegritySize]; 440 size_t ret = ComputeHmac(DIGEST_SHA_1, password.c_str(), password.size(), 441 temp_data.get(), mi_pos, hmac, sizeof(hmac)); 442 RTC_DCHECK(ret == sizeof(hmac)); 443 if (ret != sizeof(hmac)) { 444 return false; 445 } 446 447 // Comparing the calculated HMAC with the one present in the message. 448 return memcmp(data + current_pos + kStunAttributeHeaderSize, hmac, 449 mi_attr_size) == 0; 450 } 451 452 bool StunMessage::AddMessageIntegrity(absl::string_view password) { 453 return AddMessageIntegrityOfType(STUN_ATTR_MESSAGE_INTEGRITY, 454 kStunMessageIntegritySize, password); 455 } 456 457 bool StunMessage::AddMessageIntegrity32(absl::string_view password) { 458 return AddMessageIntegrityOfType(STUN_ATTR_GOOG_MESSAGE_INTEGRITY_32, 459 kStunMessageIntegrity32Size, password); 460 } 461 462 bool StunMessage::AddMessageIntegrityOfType(int attr_type, 463 size_t attr_size, 464 absl::string_view key) { 465 // Add the attribute with a dummy value. Since this is a known attribute, it 466 // can't fail. 467 RTC_DCHECK(attr_size <= kStunMessageIntegritySize); 468 auto msg_integrity_attr_ptr = std::make_unique<StunByteStringAttribute>( 469 attr_type, std::string(attr_size, '0')); 470 auto* msg_integrity_attr = msg_integrity_attr_ptr.get(); 471 AddAttribute(std::move(msg_integrity_attr_ptr)); 472 473 // Calculate the HMAC for the message. 474 ByteBufferWriter buf; 475 if (!Write(&buf)) 476 return false; 477 478 int msg_len_for_hmac = static_cast<int>( 479 buf.Length() - kStunAttributeHeaderSize - msg_integrity_attr->length()); 480 char hmac[kStunMessageIntegritySize]; 481 size_t ret = ComputeHmac(DIGEST_SHA_1, key.data(), key.size(), buf.Data(), 482 msg_len_for_hmac, hmac, sizeof(hmac)); 483 RTC_DCHECK(ret == sizeof(hmac)); 484 if (ret != sizeof(hmac)) { 485 RTC_LOG(LS_ERROR) << "HMAC computation failed. Message-Integrity " 486 "has dummy value."; 487 return false; 488 } 489 490 // Insert correct HMAC into the attribute. 491 msg_integrity_attr->CopyBytes(hmac, attr_size); 492 password_ = std::string(key); 493 integrity_ = IntegrityStatus::kIntegrityOk; 494 return true; 495 } 496 497 // Verifies a message is in fact a STUN message, by performing the checks 498 // outlined in RFC 5389, section 7.3, including the FINGERPRINT check detailed 499 // in section 15.5. 500 bool StunMessage::ValidateFingerprint(const char* data, size_t size) { 501 // Check the message length. 502 size_t fingerprint_attr_size = 503 kStunAttributeHeaderSize + StunUInt32Attribute::SIZE; 504 if (size % 4 != 0 || size < kStunHeaderSize + fingerprint_attr_size) 505 return false; 506 507 // Skip the rest if the magic cookie isn't present. 508 const char* magic_cookie = 509 data + kStunTransactionIdOffset - kStunMagicCookieLength; 510 if (GetBE32(magic_cookie) != kStunMagicCookie) 511 return false; 512 513 // Check the fingerprint type and length. 514 const char* fingerprint_attr_data = data + size - fingerprint_attr_size; 515 if (GetBE16(fingerprint_attr_data) != STUN_ATTR_FINGERPRINT || 516 GetBE16(fingerprint_attr_data + sizeof(uint16_t)) != 517 StunUInt32Attribute::SIZE) 518 return false; 519 520 // Check the fingerprint value. 521 uint32_t fingerprint = 522 GetBE32(fingerprint_attr_data + kStunAttributeHeaderSize); 523 return ((fingerprint ^ STUN_FINGERPRINT_XOR_VALUE) == 524 ComputeCrc32(data, size - fingerprint_attr_size)); 525 } 526 527 // static 528 std::string StunMessage::GenerateTransactionId() { 529 return CreateRandomString(kStunTransactionIdLength); 530 } 531 532 bool StunMessage::IsStunMethod(ArrayView<int> methods, 533 const char* data, 534 size_t size) { 535 // Check the message length. 536 if (size % 4 != 0 || size < kStunHeaderSize) 537 return false; 538 539 // Skip the rest if the magic cookie isn't present. 540 const char* magic_cookie = 541 data + kStunTransactionIdOffset - kStunMagicCookieLength; 542 if (GetBE32(magic_cookie) != kStunMagicCookie) 543 return false; 544 545 int method = GetBE16(data); 546 for (int m : methods) { 547 if (m == method) { 548 return true; 549 } 550 } 551 return false; 552 } 553 554 bool StunMessage::AddFingerprint() { 555 // Add the attribute with a dummy value. Since this is a known attribute, 556 // it can't fail. 557 auto fingerprint_attr_ptr = 558 std::make_unique<StunUInt32Attribute>(STUN_ATTR_FINGERPRINT, 0); 559 auto* fingerprint_attr = fingerprint_attr_ptr.get(); 560 AddAttribute(std::move(fingerprint_attr_ptr)); 561 562 // Calculate the CRC-32 for the message and insert it. 563 ByteBufferWriter buf; 564 if (!Write(&buf)) 565 return false; 566 567 int msg_len_for_crc32 = static_cast<int>( 568 buf.Length() - kStunAttributeHeaderSize - fingerprint_attr->length()); 569 uint32_t c = ComputeCrc32(buf.Data(), msg_len_for_crc32); 570 571 // Insert the correct CRC-32, XORed with a constant, into the attribute. 572 fingerprint_attr->SetValue(c ^ STUN_FINGERPRINT_XOR_VALUE); 573 return true; 574 } 575 576 bool StunMessage::Read(ByteBufferReader* buf) { 577 // Keep a copy of the buffer data around for later verification. 578 buffer_.assign(reinterpret_cast<const char*>(buf->Data()), buf->Length()); 579 580 if (!buf->ReadUInt16(&type_)) { 581 return false; 582 } 583 584 if (type_ & 0x8000) { 585 // RTP and RTCP set the MSB of first byte, since first two bits are version, 586 // and version is always 2 (10). If set, this is not a STUN packet. 587 return false; 588 } 589 590 if (!buf->ReadUInt16(&length_)) { 591 return false; 592 } 593 594 absl::string_view magic_cookie; 595 if (!buf->ReadStringView(&magic_cookie, kStunMagicCookieLength)) { 596 return false; 597 } 598 599 std::string transaction_id; 600 if (!buf->ReadString(&transaction_id, kStunTransactionIdLength)) { 601 return false; 602 } 603 604 uint32_t magic_cookie_int; 605 static_assert(sizeof(magic_cookie_int) == kStunMagicCookieLength, 606 "Integer size mismatch: magic_cookie_int and kStunMagicCookie"); 607 std::memcpy(&magic_cookie_int, magic_cookie.data(), sizeof(magic_cookie_int)); 608 if (NetworkToHost32(magic_cookie_int) != kStunMagicCookie) { 609 // If magic cookie is invalid it means that the peer implements 610 // RFC3489 instead of RFC5389. 611 transaction_id.insert(0, magic_cookie); 612 } 613 RTC_DCHECK(IsValidTransactionId(transaction_id)); 614 transaction_id_ = transaction_id; 615 reduced_transaction_id_ = ReduceTransactionId(transaction_id_); 616 617 if (length_ != buf->Length()) { 618 return false; 619 } 620 621 attrs_.resize(0); 622 623 size_t rest = buf->Length() - length_; 624 while (buf->Length() > rest) { 625 uint16_t attr_type, attr_length; 626 if (!buf->ReadUInt16(&attr_type)) 627 return false; 628 if (!buf->ReadUInt16(&attr_length)) 629 return false; 630 631 std::unique_ptr<StunAttribute> attr( 632 CreateAttribute(attr_type, attr_length)); 633 if (!attr) { 634 // Skip any unknown or malformed attributes. 635 if ((attr_length % 4) != 0) { 636 attr_length += (4 - (attr_length % 4)); 637 } 638 if (!buf->Consume(attr_length)) { 639 return false; 640 } 641 } else { 642 if (!attr->Read(buf)) { 643 return false; 644 } 645 attrs_.push_back(std::move(attr)); 646 } 647 } 648 649 RTC_DCHECK(buf->Length() == rest); 650 return true; 651 } 652 653 bool StunMessage::Write(ByteBufferWriter* buf) const { 654 buf->WriteUInt16(type_); 655 buf->WriteUInt16(length_); 656 if (!IsLegacy()) 657 buf->WriteUInt32(stun_magic_cookie_); 658 buf->WriteString(transaction_id_); 659 660 for (const auto& attr : attrs_) { 661 buf->WriteUInt16(attr->type()); 662 buf->WriteUInt16(static_cast<uint16_t>(attr->length())); 663 if (!attr->Write(buf)) { 664 return false; 665 } 666 } 667 668 return true; 669 } 670 671 StunMessage* StunMessage::CreateNew() const { 672 return new StunMessage(); 673 } 674 675 void StunMessage::SetStunMagicCookie(uint32_t val) { 676 stun_magic_cookie_ = val; 677 } 678 679 void StunMessage::SetTransactionIdForTesting(absl::string_view transaction_id) { 680 RTC_DCHECK(IsValidTransactionId(transaction_id)); 681 transaction_id_ = std::string(transaction_id); 682 reduced_transaction_id_ = ReduceTransactionId(transaction_id_); 683 } 684 685 StunAttributeValueType StunMessage::GetAttributeValueType(int type) const { 686 switch (type) { 687 case STUN_ATTR_MAPPED_ADDRESS: 688 return STUN_VALUE_ADDRESS; 689 case STUN_ATTR_USERNAME: 690 return STUN_VALUE_BYTE_STRING; 691 case STUN_ATTR_MESSAGE_INTEGRITY: 692 return STUN_VALUE_BYTE_STRING; 693 case STUN_ATTR_ERROR_CODE: 694 return STUN_VALUE_ERROR_CODE; 695 case STUN_ATTR_UNKNOWN_ATTRIBUTES: 696 return STUN_VALUE_UINT16_LIST; 697 case STUN_ATTR_REALM: 698 return STUN_VALUE_BYTE_STRING; 699 case STUN_ATTR_NONCE: 700 return STUN_VALUE_BYTE_STRING; 701 case STUN_ATTR_XOR_MAPPED_ADDRESS: 702 return STUN_VALUE_XOR_ADDRESS; 703 case STUN_ATTR_SOFTWARE: 704 return STUN_VALUE_BYTE_STRING; 705 case STUN_ATTR_ALTERNATE_SERVER: 706 return STUN_VALUE_ADDRESS; 707 case STUN_ATTR_FINGERPRINT: 708 return STUN_VALUE_UINT32; 709 case STUN_ATTR_RETRANSMIT_COUNT: 710 return STUN_VALUE_UINT32; 711 case STUN_ATTR_GOOG_LAST_ICE_CHECK_RECEIVED: 712 return STUN_VALUE_BYTE_STRING; 713 case STUN_ATTR_GOOG_MISC_INFO: 714 return STUN_VALUE_UINT16_LIST; 715 case STUN_ATTR_GOOG_DELTA: 716 return STUN_VALUE_BYTE_STRING; 717 case STUN_ATTR_GOOG_DELTA_ACK: 718 return STUN_VALUE_UINT64; 719 default: 720 return STUN_VALUE_UNKNOWN; 721 } 722 } 723 724 StunAttribute* StunMessage::CreateAttribute(int type, size_t length) /*const*/ { 725 StunAttributeValueType value_type = GetAttributeValueType(type); 726 if (value_type != STUN_VALUE_UNKNOWN) { 727 return StunAttribute::Create(value_type, type, 728 static_cast<uint16_t>(length), this); 729 } else if (DesignatedExpertRange(type)) { 730 // Read unknown attributes as STUN_VALUE_BYTE_STRING 731 return StunAttribute::Create(STUN_VALUE_BYTE_STRING, type, 732 static_cast<uint16_t>(length), this); 733 } else { 734 return nullptr; 735 } 736 } 737 738 const StunAttribute* StunMessage::GetAttribute(int type) const { 739 for (const auto& attr : attrs_) { 740 if (attr->type() == type) { 741 return attr.get(); 742 } 743 } 744 return nullptr; 745 } 746 747 bool StunMessage::IsValidTransactionId(absl::string_view transaction_id) { 748 return transaction_id.size() == kStunTransactionIdLength || 749 transaction_id.size() == kStunLegacyTransactionIdLength; 750 } 751 752 bool StunMessage::EqualAttributes( 753 const StunMessage* other, 754 std::function<bool(int type)> attribute_type_mask) const { 755 RTC_DCHECK(other != nullptr); 756 ByteBufferWriter tmp_buffer_ptr1; 757 ByteBufferWriter tmp_buffer_ptr2; 758 for (const auto& attr : attrs_) { 759 if (attribute_type_mask(attr->type())) { 760 const StunAttribute* other_attr = other->GetAttribute(attr->type()); 761 if (other_attr == nullptr) { 762 return false; 763 } 764 tmp_buffer_ptr1.Clear(); 765 tmp_buffer_ptr2.Clear(); 766 attr->Write(&tmp_buffer_ptr1); 767 other_attr->Write(&tmp_buffer_ptr2); 768 if (tmp_buffer_ptr1.Length() != tmp_buffer_ptr2.Length()) { 769 return false; 770 } 771 if (memcmp(tmp_buffer_ptr1.Data(), tmp_buffer_ptr2.Data(), 772 tmp_buffer_ptr1.Length()) != 0) { 773 return false; 774 } 775 } 776 } 777 778 for (const auto& attr : other->attrs_) { 779 if (attribute_type_mask(attr->type())) { 780 const StunAttribute* own_attr = GetAttribute(attr->type()); 781 if (own_attr == nullptr) { 782 return false; 783 } 784 // we have already compared all values... 785 } 786 } 787 return true; 788 } 789 790 // StunAttribute 791 792 StunAttribute::StunAttribute(uint16_t type, uint16_t length) 793 : type_(type), length_(length) {} 794 795 void StunAttribute::ConsumePadding(ByteBufferReader* buf) const { 796 int remainder = length_ % 4; 797 if (remainder > 0) { 798 buf->Consume(4 - remainder); 799 } 800 } 801 802 void StunAttribute::WritePadding(ByteBufferWriter* buf) const { 803 int remainder = length_ % 4; 804 if (remainder > 0) { 805 uint8_t zeroes[4] = {0}; 806 buf->Write(ArrayView<const uint8_t>(zeroes, 4 - remainder)); 807 } 808 } 809 810 StunAttribute* StunAttribute::Create(StunAttributeValueType value_type, 811 uint16_t type, 812 uint16_t length, 813 StunMessage* owner) { 814 switch (value_type) { 815 case STUN_VALUE_ADDRESS: 816 return new StunAddressAttribute(type, length); 817 case STUN_VALUE_XOR_ADDRESS: 818 return new StunXorAddressAttribute(type, length, owner); 819 case STUN_VALUE_UINT32: 820 return new StunUInt32Attribute(type); 821 case STUN_VALUE_UINT64: 822 return new StunUInt64Attribute(type); 823 case STUN_VALUE_BYTE_STRING: 824 return new StunByteStringAttribute(type, length); 825 case STUN_VALUE_ERROR_CODE: 826 return new StunErrorCodeAttribute(type, length); 827 case STUN_VALUE_UINT16_LIST: 828 return new StunUInt16ListAttribute(type, length); 829 default: 830 return nullptr; 831 } 832 } 833 834 std::unique_ptr<StunAddressAttribute> StunAttribute::CreateAddress( 835 uint16_t type) { 836 return std::make_unique<StunAddressAttribute>(type, 0); 837 } 838 839 std::unique_ptr<StunXorAddressAttribute> StunAttribute::CreateXorAddress( 840 uint16_t type) { 841 return std::make_unique<StunXorAddressAttribute>(type, 0, nullptr); 842 } 843 844 std::unique_ptr<StunUInt64Attribute> StunAttribute::CreateUInt64( 845 uint16_t type) { 846 return std::make_unique<StunUInt64Attribute>(type); 847 } 848 849 std::unique_ptr<StunUInt32Attribute> StunAttribute::CreateUInt32( 850 uint16_t type) { 851 return std::make_unique<StunUInt32Attribute>(type); 852 } 853 854 std::unique_ptr<StunByteStringAttribute> StunAttribute::CreateByteString( 855 uint16_t type) { 856 return std::make_unique<StunByteStringAttribute>(type, 0); 857 } 858 859 std::unique_ptr<StunErrorCodeAttribute> StunAttribute::CreateErrorCode() { 860 return std::make_unique<StunErrorCodeAttribute>( 861 STUN_ATTR_ERROR_CODE, StunErrorCodeAttribute::MIN_SIZE); 862 } 863 864 std::unique_ptr<StunUInt16ListAttribute> 865 StunAttribute::CreateUInt16ListAttribute(uint16_t type) { 866 return std::make_unique<StunUInt16ListAttribute>(type, 0); 867 } 868 869 std::unique_ptr<StunUInt16ListAttribute> 870 StunAttribute::CreateUnknownAttributes() { 871 return std::make_unique<StunUInt16ListAttribute>(STUN_ATTR_UNKNOWN_ATTRIBUTES, 872 0); 873 } 874 875 StunAddressAttribute::StunAddressAttribute(uint16_t type, 876 const SocketAddress& addr) 877 : StunAttribute(type, 0) { 878 SetAddress(addr); 879 } 880 881 StunAddressAttribute::StunAddressAttribute(uint16_t type, uint16_t length) 882 : StunAttribute(type, length) {} 883 884 StunAttributeValueType StunAddressAttribute::value_type() const { 885 return STUN_VALUE_ADDRESS; 886 } 887 888 bool StunAddressAttribute::Read(ByteBufferReader* buf) { 889 uint8_t dummy; 890 if (!buf->ReadUInt8(&dummy)) 891 return false; 892 893 uint8_t stun_family; 894 if (!buf->ReadUInt8(&stun_family)) { 895 return false; 896 } 897 uint16_t port; 898 if (!buf->ReadUInt16(&port)) 899 return false; 900 if (stun_family == STUN_ADDRESS_IPV4) { 901 in_addr v4addr; 902 if (length() != SIZE_IP4) { 903 return false; 904 } 905 if (!buf->ReadBytes(MakeArrayView(reinterpret_cast<uint8_t*>(&v4addr), 906 sizeof(v4addr)))) { 907 return false; 908 } 909 IPAddress ipaddr(v4addr); 910 SetAddress(SocketAddress(ipaddr, port)); 911 } else if (stun_family == STUN_ADDRESS_IPV6) { 912 in6_addr v6addr; 913 if (length() != SIZE_IP6) { 914 return false; 915 } 916 if (!buf->ReadBytes(MakeArrayView(reinterpret_cast<uint8_t*>(&v6addr), 917 sizeof(v6addr)))) { 918 return false; 919 } 920 IPAddress ipaddr(v6addr); 921 SetAddress(SocketAddress(ipaddr, port)); 922 } else { 923 return false; 924 } 925 return true; 926 } 927 928 bool StunAddressAttribute::Write(ByteBufferWriter* buf) const { 929 StunAddressFamily address_family = family(); 930 if (address_family == STUN_ADDRESS_UNDEF) { 931 RTC_LOG(LS_ERROR) << "Error writing address attribute: unknown family."; 932 return false; 933 } 934 buf->WriteUInt8(0); 935 buf->WriteUInt8(address_family); 936 buf->WriteUInt16(address_.port()); 937 switch (address_.family()) { 938 case AF_INET: { 939 in_addr v4addr = address_.ipaddr().ipv4_address(); 940 buf->Write(ArrayView<const uint8_t>(reinterpret_cast<uint8_t*>(&v4addr), 941 sizeof(v4addr))); 942 break; 943 } 944 case AF_INET6: { 945 in6_addr v6addr = address_.ipaddr().ipv6_address(); 946 buf->Write(ArrayView<const uint8_t>(reinterpret_cast<uint8_t*>(&v6addr), 947 sizeof(v6addr))); 948 break; 949 } 950 } 951 return true; 952 } 953 954 StunXorAddressAttribute::StunXorAddressAttribute(uint16_t type, 955 const SocketAddress& addr) 956 : StunAddressAttribute(type, addr), owner_(nullptr) {} 957 958 StunXorAddressAttribute::StunXorAddressAttribute(uint16_t type, 959 uint16_t length, 960 StunMessage* owner) 961 : StunAddressAttribute(type, length), owner_(owner) {} 962 963 StunAttributeValueType StunXorAddressAttribute::value_type() const { 964 return STUN_VALUE_XOR_ADDRESS; 965 } 966 967 void StunXorAddressAttribute::SetOwner(StunMessage* owner) { 968 owner_ = owner; 969 } 970 971 IPAddress StunXorAddressAttribute::GetXoredIP() const { 972 if (owner_) { 973 IPAddress ip = ipaddr(); 974 switch (ip.family()) { 975 case AF_INET: { 976 in_addr v4addr = ip.ipv4_address(); 977 v4addr.s_addr = (v4addr.s_addr ^ HostToNetwork32(kStunMagicCookie)); 978 return IPAddress(v4addr); 979 } 980 case AF_INET6: { 981 in6_addr v6addr = ip.ipv6_address(); 982 const std::string& transaction_id = owner_->transaction_id(); 983 if (transaction_id.length() == kStunTransactionIdLength) { 984 uint32_t transactionid_as_ints[3]; 985 memcpy(&transactionid_as_ints[0], transaction_id.c_str(), 986 transaction_id.length()); 987 uint32_t* ip_as_ints = reinterpret_cast<uint32_t*>(&v6addr.s6_addr); 988 // Transaction ID is in network byte order, but magic cookie 989 // is stored in host byte order. 990 ip_as_ints[0] = (ip_as_ints[0] ^ HostToNetwork32(kStunMagicCookie)); 991 ip_as_ints[1] = (ip_as_ints[1] ^ transactionid_as_ints[0]); 992 ip_as_ints[2] = (ip_as_ints[2] ^ transactionid_as_ints[1]); 993 ip_as_ints[3] = (ip_as_ints[3] ^ transactionid_as_ints[2]); 994 return IPAddress(v6addr); 995 } 996 break; 997 } 998 } 999 } 1000 // Invalid ip family or transaction ID, or missing owner. 1001 // Return an AF_UNSPEC address. 1002 return IPAddress(); 1003 } 1004 1005 bool StunXorAddressAttribute::Read(ByteBufferReader* buf) { 1006 if (!StunAddressAttribute::Read(buf)) 1007 return false; 1008 uint16_t xoredport = port() ^ (kStunMagicCookie >> 16); 1009 IPAddress xored_ip = GetXoredIP(); 1010 SetAddress(SocketAddress(xored_ip, xoredport)); 1011 return true; 1012 } 1013 1014 bool StunXorAddressAttribute::Write(ByteBufferWriter* buf) const { 1015 StunAddressFamily address_family = family(); 1016 if (address_family == STUN_ADDRESS_UNDEF) { 1017 RTC_LOG(LS_ERROR) << "Error writing xor-address attribute: unknown family."; 1018 return false; 1019 } 1020 IPAddress xored_ip = GetXoredIP(); 1021 if (xored_ip.family() == AF_UNSPEC) { 1022 return false; 1023 } 1024 buf->WriteUInt8(0); 1025 buf->WriteUInt8(family()); 1026 buf->WriteUInt16(port() ^ (kStunMagicCookie >> 16)); 1027 switch (xored_ip.family()) { 1028 case AF_INET: { 1029 in_addr v4addr = xored_ip.ipv4_address(); 1030 buf->Write(ArrayView<const uint8_t>( 1031 reinterpret_cast<const uint8_t*>(&v4addr), sizeof(v4addr))); 1032 break; 1033 } 1034 case AF_INET6: { 1035 in6_addr v6addr = xored_ip.ipv6_address(); 1036 buf->Write(ArrayView<const uint8_t>( 1037 reinterpret_cast<const uint8_t*>(&v6addr), sizeof(v6addr))); 1038 break; 1039 } 1040 } 1041 return true; 1042 } 1043 1044 StunUInt32Attribute::StunUInt32Attribute(uint16_t type, uint32_t value) 1045 : StunAttribute(type, SIZE), bits_(value) {} 1046 1047 StunUInt32Attribute::StunUInt32Attribute(uint16_t type) 1048 : StunAttribute(type, SIZE), bits_(0) {} 1049 1050 StunAttributeValueType StunUInt32Attribute::value_type() const { 1051 return STUN_VALUE_UINT32; 1052 } 1053 1054 bool StunUInt32Attribute::GetBit(size_t index) const { 1055 RTC_DCHECK(index < 32); 1056 return static_cast<bool>((bits_ >> index) & 0x1); 1057 } 1058 1059 void StunUInt32Attribute::SetBit(size_t index, bool value) { 1060 RTC_DCHECK(index < 32); 1061 bits_ &= ~(1 << index); 1062 bits_ |= value ? (1 << index) : 0; 1063 } 1064 1065 bool StunUInt32Attribute::Read(ByteBufferReader* buf) { 1066 if (length() != SIZE || !buf->ReadUInt32(&bits_)) 1067 return false; 1068 return true; 1069 } 1070 1071 bool StunUInt32Attribute::Write(ByteBufferWriter* buf) const { 1072 buf->WriteUInt32(bits_); 1073 return true; 1074 } 1075 1076 StunUInt64Attribute::StunUInt64Attribute(uint16_t type, uint64_t value) 1077 : StunAttribute(type, SIZE), bits_(value) {} 1078 1079 StunUInt64Attribute::StunUInt64Attribute(uint16_t type) 1080 : StunAttribute(type, SIZE), bits_(0) {} 1081 1082 StunAttributeValueType StunUInt64Attribute::value_type() const { 1083 return STUN_VALUE_UINT64; 1084 } 1085 1086 bool StunUInt64Attribute::Read(ByteBufferReader* buf) { 1087 if (length() != SIZE || !buf->ReadUInt64(&bits_)) 1088 return false; 1089 return true; 1090 } 1091 1092 bool StunUInt64Attribute::Write(ByteBufferWriter* buf) const { 1093 buf->WriteUInt64(bits_); 1094 return true; 1095 } 1096 1097 StunByteStringAttribute::StunByteStringAttribute(uint16_t type) 1098 : StunAttribute(type, 0), bytes_(nullptr) {} 1099 1100 StunByteStringAttribute::StunByteStringAttribute(uint16_t type, 1101 absl::string_view str) 1102 : StunAttribute(type, 0), bytes_(nullptr) { 1103 CopyBytes(str); 1104 } 1105 1106 StunByteStringAttribute::StunByteStringAttribute(uint16_t type, 1107 const void* bytes, 1108 size_t length) 1109 : StunAttribute(type, 0), bytes_(nullptr) { 1110 CopyBytes(bytes, length); 1111 } 1112 1113 StunByteStringAttribute::StunByteStringAttribute( 1114 uint16_t type, 1115 const std::vector<uint32_t>& values) 1116 : StunAttribute(type, 0), bytes_(nullptr) { 1117 ByteBufferWriter writer; 1118 for (const auto& value : values) { 1119 writer.WriteUInt32(value); 1120 } 1121 CopyBytes(writer.Data(), writer.Length()); 1122 } 1123 1124 StunByteStringAttribute::StunByteStringAttribute(uint16_t type, uint16_t length) 1125 : StunAttribute(type, length), bytes_(nullptr) {} 1126 1127 StunByteStringAttribute::~StunByteStringAttribute() { 1128 delete[] bytes_; 1129 } 1130 1131 StunAttributeValueType StunByteStringAttribute::value_type() const { 1132 return STUN_VALUE_BYTE_STRING; 1133 } 1134 1135 std::optional<std::vector<uint32_t>> StunByteStringAttribute::GetUInt32Vector() 1136 const { 1137 if (length() % 4 != 0) { 1138 return std::nullopt; 1139 } 1140 std::vector<uint32_t> values; 1141 ByteBufferReader reader(array_view()); 1142 uint32_t value; 1143 while (reader.ReadUInt32(&value)) { 1144 values.push_back(value); 1145 } 1146 return values; 1147 } 1148 1149 void StunByteStringAttribute::CopyBytes(absl::string_view bytes) { 1150 uint8_t* new_bytes = new uint8_t[bytes.size()]; 1151 memcpy(new_bytes, bytes.data(), bytes.size()); 1152 SetBytes(new_bytes, bytes.size()); 1153 } 1154 1155 void StunByteStringAttribute::CopyBytes(const void* bytes, size_t length) { 1156 uint8_t* new_bytes = new uint8_t[length]; 1157 memcpy(new_bytes, bytes, length); 1158 SetBytes(new_bytes, length); 1159 } 1160 1161 uint8_t StunByteStringAttribute::GetByte(size_t index) const { 1162 RTC_DCHECK(bytes_ != nullptr); 1163 RTC_DCHECK(index < length()); 1164 return bytes_[index]; 1165 } 1166 1167 void StunByteStringAttribute::SetByte(size_t index, uint8_t value) { 1168 RTC_DCHECK(bytes_ != nullptr); 1169 RTC_DCHECK(index < length()); 1170 bytes_[index] = value; 1171 } 1172 1173 bool StunByteStringAttribute::Read(ByteBufferReader* buf) { 1174 bytes_ = new uint8_t[length()]; 1175 if (!buf->ReadBytes(ArrayView<uint8_t>(bytes_, length()))) { 1176 return false; 1177 } 1178 1179 ConsumePadding(buf); 1180 return true; 1181 } 1182 1183 bool StunByteStringAttribute::Write(ByteBufferWriter* buf) const { 1184 // Check that length is legal according to specs 1185 if (!LengthValid(type(), length())) { 1186 return false; 1187 } 1188 buf->Write(ArrayView<const uint8_t>(bytes_, length())); 1189 WritePadding(buf); 1190 return true; 1191 } 1192 1193 void StunByteStringAttribute::SetBytes(uint8_t* bytes, size_t length) { 1194 delete[] bytes_; 1195 bytes_ = bytes; 1196 SetLength(static_cast<uint16_t>(length)); 1197 } 1198 1199 const uint16_t StunErrorCodeAttribute::MIN_SIZE = 4; 1200 1201 StunErrorCodeAttribute::StunErrorCodeAttribute(uint16_t type, 1202 int code, 1203 const std::string& reason) 1204 : StunAttribute(type, 0) { 1205 SetCode(code); 1206 SetReason(reason); 1207 } 1208 1209 StunErrorCodeAttribute::StunErrorCodeAttribute(uint16_t type, uint16_t length) 1210 : StunAttribute(type, length), class_(0), number_(0) {} 1211 1212 StunErrorCodeAttribute::~StunErrorCodeAttribute() {} 1213 1214 StunAttributeValueType StunErrorCodeAttribute::value_type() const { 1215 return STUN_VALUE_ERROR_CODE; 1216 } 1217 1218 int StunErrorCodeAttribute::code() const { 1219 return class_ * 100 + number_; 1220 } 1221 1222 void StunErrorCodeAttribute::SetCode(int code) { 1223 class_ = static_cast<uint8_t>(code / 100); 1224 number_ = static_cast<uint8_t>(code % 100); 1225 } 1226 1227 void StunErrorCodeAttribute::SetReason(const std::string& reason) { 1228 SetLength(MIN_SIZE + static_cast<uint16_t>(reason.size())); 1229 reason_ = reason; 1230 } 1231 1232 bool StunErrorCodeAttribute::Read(ByteBufferReader* buf) { 1233 uint32_t val; 1234 if (length() < MIN_SIZE || !buf->ReadUInt32(&val)) 1235 return false; 1236 1237 if ((val >> 11) != 0) 1238 RTC_LOG(LS_ERROR) << "error-code bits not zero"; 1239 1240 class_ = ((val >> 8) & 0x7); 1241 number_ = (val & 0xff); 1242 1243 if (!buf->ReadString(&reason_, length() - 4)) 1244 return false; 1245 1246 ConsumePadding(buf); 1247 return true; 1248 } 1249 1250 bool StunErrorCodeAttribute::Write(ByteBufferWriter* buf) const { 1251 buf->WriteUInt32(class_ << 8 | number_); 1252 buf->WriteString(reason_); 1253 WritePadding(buf); 1254 return true; 1255 } 1256 1257 StunUInt16ListAttribute::StunUInt16ListAttribute(uint16_t type, uint16_t length) 1258 : StunAttribute(type, length) { 1259 attr_types_ = new std::vector<uint16_t>(); 1260 } 1261 1262 StunUInt16ListAttribute::~StunUInt16ListAttribute() { 1263 delete attr_types_; 1264 } 1265 1266 StunAttributeValueType StunUInt16ListAttribute::value_type() const { 1267 return STUN_VALUE_UINT16_LIST; 1268 } 1269 1270 size_t StunUInt16ListAttribute::Size() const { 1271 return attr_types_->size(); 1272 } 1273 1274 uint16_t StunUInt16ListAttribute::GetType(int index) const { 1275 return (*attr_types_)[index]; 1276 } 1277 1278 void StunUInt16ListAttribute::SetType(int index, uint16_t value) { 1279 (*attr_types_)[index] = value; 1280 } 1281 1282 void StunUInt16ListAttribute::AddType(uint16_t value) { 1283 attr_types_->push_back(value); 1284 SetLength(static_cast<uint16_t>(attr_types_->size() * 2)); 1285 } 1286 1287 void StunUInt16ListAttribute::AddTypeAtIndex(uint16_t index, uint16_t value) { 1288 if (attr_types_->size() < static_cast<size_t>(index + 1)) { 1289 attr_types_->resize(index + 1); 1290 } 1291 (*attr_types_)[index] = value; 1292 SetLength(static_cast<uint16_t>(attr_types_->size() * 2)); 1293 } 1294 1295 bool StunUInt16ListAttribute::Read(ByteBufferReader* buf) { 1296 if (length() % 2) { 1297 return false; 1298 } 1299 1300 for (size_t i = 0; i < length() / 2; i++) { 1301 uint16_t attr; 1302 if (!buf->ReadUInt16(&attr)) 1303 return false; 1304 attr_types_->push_back(attr); 1305 } 1306 // Padding of these attributes is done in RFC 5389 style. This is 1307 // slightly different from RFC3489, but it shouldn't be important. 1308 // RFC3489 pads out to a 32 bit boundary by duplicating one of the 1309 // entries in the list (not necessarily the last one - it's unspecified). 1310 // RFC5389 pads on the end, and the bytes are always ignored. 1311 ConsumePadding(buf); 1312 return true; 1313 } 1314 1315 bool StunUInt16ListAttribute::Write(ByteBufferWriter* buf) const { 1316 for (size_t i = 0; i < attr_types_->size(); ++i) { 1317 buf->WriteUInt16((*attr_types_)[i]); 1318 } 1319 WritePadding(buf); 1320 return true; 1321 } 1322 1323 std::string StunMethodToString(int msg_type) { 1324 switch (msg_type) { 1325 case STUN_BINDING_REQUEST: 1326 return "STUN BINDING request"; 1327 case STUN_BINDING_INDICATION: 1328 return "STUN BINDING indication"; 1329 case STUN_BINDING_RESPONSE: 1330 return "STUN BINDING response"; 1331 case STUN_BINDING_ERROR_RESPONSE: 1332 return "STUN BINDING error response"; 1333 case GOOG_PING_REQUEST: 1334 return "GOOG PING request"; 1335 case GOOG_PING_RESPONSE: 1336 return "GOOG PING response"; 1337 case GOOG_PING_ERROR_RESPONSE: 1338 return "GOOG PING error response"; 1339 case STUN_ALLOCATE_REQUEST: 1340 return "TURN ALLOCATE request"; 1341 case STUN_ALLOCATE_RESPONSE: 1342 return "TURN ALLOCATE response"; 1343 case STUN_ALLOCATE_ERROR_RESPONSE: 1344 return "TURN ALLOCATE error response"; 1345 case TURN_REFRESH_REQUEST: 1346 return "TURN REFRESH request"; 1347 case TURN_REFRESH_RESPONSE: 1348 return "TURN REFRESH response"; 1349 case TURN_REFRESH_ERROR_RESPONSE: 1350 return "TURN REFRESH error response"; 1351 case TURN_SEND_INDICATION: 1352 return "TURN SEND INDICATION"; 1353 case TURN_DATA_INDICATION: 1354 return "TURN DATA INDICATION"; 1355 case TURN_CREATE_PERMISSION_REQUEST: 1356 return "TURN CREATE PERMISSION request"; 1357 case TURN_CREATE_PERMISSION_RESPONSE: 1358 return "TURN CREATE PERMISSION response"; 1359 case TURN_CREATE_PERMISSION_ERROR_RESPONSE: 1360 return "TURN CREATE PERMISSION error response"; 1361 case TURN_CHANNEL_BIND_REQUEST: 1362 return "TURN CHANNEL BIND request"; 1363 case TURN_CHANNEL_BIND_RESPONSE: 1364 return "TURN CHANNEL BIND response"; 1365 case TURN_CHANNEL_BIND_ERROR_RESPONSE: 1366 return "TURN CHANNEL BIND error response"; 1367 default: 1368 return "UNKNOWN<" + std::to_string(msg_type) + ">"; 1369 } 1370 } 1371 1372 int GetStunSuccessResponseType(int req_type) { 1373 return IsStunRequestType(req_type) ? (req_type | 0x100) : -1; 1374 } 1375 1376 int GetStunErrorResponseType(int req_type) { 1377 return IsStunRequestType(req_type) ? (req_type | 0x110) : -1; 1378 } 1379 1380 bool IsStunRequestType(int msg_type) { 1381 return ((msg_type & kStunTypeMask) == 0x000); 1382 } 1383 1384 bool IsStunIndicationType(int msg_type) { 1385 return ((msg_type & kStunTypeMask) == 0x010); 1386 } 1387 1388 bool IsStunSuccessResponseType(int msg_type) { 1389 return ((msg_type & kStunTypeMask) == 0x100); 1390 } 1391 1392 bool IsStunErrorResponseType(int msg_type) { 1393 return ((msg_type & kStunTypeMask) == 0x110); 1394 } 1395 1396 bool ComputeStunCredentialHash(const std::string& username, 1397 const std::string& realm, 1398 const std::string& password, 1399 std::string* hash) { 1400 // http://tools.ietf.org/html/rfc5389#section-15.4 1401 // long-term credentials will be calculated using the key and key is 1402 // key = MD5(username ":" realm ":" SASLprep(password)) 1403 std::string input = username; 1404 input += ':'; 1405 input += realm; 1406 input += ':'; 1407 input += password; 1408 1409 char digest[MessageDigest::kMaxSize]; 1410 size_t size = ComputeDigest(DIGEST_MD5, input.c_str(), input.size(), digest, 1411 sizeof(digest)); 1412 if (size == 0) { 1413 return false; 1414 } 1415 1416 *hash = std::string(digest, size); 1417 return true; 1418 } 1419 1420 std::unique_ptr<StunAttribute> CopyStunAttribute( 1421 const StunAttribute& attribute, 1422 ByteBufferWriter* tmp_buffer_ptr) { 1423 ByteBufferWriter tmpBuffer; 1424 if (tmp_buffer_ptr == nullptr) { 1425 tmp_buffer_ptr = &tmpBuffer; 1426 } 1427 1428 std::unique_ptr<StunAttribute> copy(StunAttribute::Create( 1429 attribute.value_type(), attribute.type(), 1430 static_cast<uint16_t>(attribute.length()), nullptr)); 1431 1432 if (!copy) { 1433 return nullptr; 1434 } 1435 tmp_buffer_ptr->Clear(); 1436 if (!attribute.Write(tmp_buffer_ptr)) { 1437 return nullptr; 1438 } 1439 ByteBufferReader reader(*tmp_buffer_ptr); 1440 if (!copy->Read(&reader)) { 1441 return nullptr; 1442 } 1443 1444 return copy; 1445 } 1446 1447 StunAttributeValueType TurnMessage::GetAttributeValueType(int type) const { 1448 switch (type) { 1449 case STUN_ATTR_CHANNEL_NUMBER: 1450 return STUN_VALUE_UINT32; 1451 case STUN_ATTR_LIFETIME: 1452 return STUN_VALUE_UINT32; 1453 case STUN_ATTR_XOR_PEER_ADDRESS: 1454 return STUN_VALUE_XOR_ADDRESS; 1455 case STUN_ATTR_DATA: 1456 return STUN_VALUE_BYTE_STRING; 1457 case STUN_ATTR_XOR_RELAYED_ADDRESS: 1458 return STUN_VALUE_XOR_ADDRESS; 1459 case STUN_ATTR_EVEN_PORT: 1460 return STUN_VALUE_BYTE_STRING; 1461 case STUN_ATTR_REQUESTED_TRANSPORT: 1462 return STUN_VALUE_UINT32; 1463 case STUN_ATTR_DONT_FRAGMENT: 1464 return STUN_VALUE_BYTE_STRING; 1465 case STUN_ATTR_RESERVATION_TOKEN: 1466 return STUN_VALUE_BYTE_STRING; 1467 default: 1468 return StunMessage::GetAttributeValueType(type); 1469 } 1470 } 1471 1472 StunMessage* TurnMessage::CreateNew() const { 1473 return new TurnMessage(); 1474 } 1475 1476 StunAttributeValueType IceMessage::GetAttributeValueType(int type) const { 1477 switch (type) { 1478 case STUN_ATTR_PRIORITY: 1479 case STUN_ATTR_GOOG_NETWORK_INFO: 1480 case STUN_ATTR_NOMINATION: 1481 return STUN_VALUE_UINT32; 1482 case STUN_ATTR_USE_CANDIDATE: 1483 return STUN_VALUE_BYTE_STRING; 1484 case STUN_ATTR_ICE_CONTROLLED: 1485 return STUN_VALUE_UINT64; 1486 case STUN_ATTR_ICE_CONTROLLING: 1487 return STUN_VALUE_UINT64; 1488 default: 1489 return StunMessage::GetAttributeValueType(type); 1490 } 1491 } 1492 1493 StunMessage* IceMessage::CreateNew() const { 1494 return new IceMessage(); 1495 } 1496 1497 std::unique_ptr<StunMessage> StunMessage::Clone() const { 1498 std::unique_ptr<StunMessage> copy(CreateNew()); 1499 if (!copy) { 1500 return nullptr; 1501 } 1502 ByteBufferWriter buf; 1503 if (!Write(&buf)) { 1504 return nullptr; 1505 } 1506 ByteBufferReader reader(buf); 1507 if (!copy->Read(&reader)) { 1508 return nullptr; 1509 } 1510 return copy; 1511 } 1512 1513 } // namespace webrtc