OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/p2p/base/stun.h" | 11 #include "webrtc/p2p/base/stun.h" |
12 | 12 |
13 #include <string.h> | 13 #include <string.h> |
14 | 14 |
15 #include <memory> | 15 #include <memory> |
16 | 16 |
17 #include "webrtc/base/byteorder.h" | 17 #include "webrtc/base/byteorder.h" |
| 18 #include "webrtc/base/checks.h" |
18 #include "webrtc/base/common.h" | 19 #include "webrtc/base/common.h" |
19 #include "webrtc/base/crc32.h" | 20 #include "webrtc/base/crc32.h" |
20 #include "webrtc/base/logging.h" | 21 #include "webrtc/base/logging.h" |
21 #include "webrtc/base/messagedigest.h" | 22 #include "webrtc/base/messagedigest.h" |
22 #include "webrtc/base/stringencode.h" | 23 #include "webrtc/base/stringencode.h" |
23 | 24 |
24 using rtc::ByteBufferReader; | 25 using rtc::ByteBufferReader; |
25 using rtc::ByteBufferWriter; | 26 using rtc::ByteBufferWriter; |
26 | 27 |
27 namespace cricket { | 28 namespace cricket { |
(...skipping 13 matching lines...) Expand all Loading... |
41 const char TURN_MAGIC_COOKIE_VALUE[] = { '\x72', '\xC6', '\x4B', '\xC6' }; | 42 const char TURN_MAGIC_COOKIE_VALUE[] = { '\x72', '\xC6', '\x4B', '\xC6' }; |
42 const char EMPTY_TRANSACTION_ID[] = "0000000000000000"; | 43 const char EMPTY_TRANSACTION_ID[] = "0000000000000000"; |
43 const uint32_t STUN_FINGERPRINT_XOR_VALUE = 0x5354554E; | 44 const uint32_t STUN_FINGERPRINT_XOR_VALUE = 0x5354554E; |
44 | 45 |
45 // StunMessage | 46 // StunMessage |
46 | 47 |
47 StunMessage::StunMessage() | 48 StunMessage::StunMessage() |
48 : type_(0), | 49 : type_(0), |
49 length_(0), | 50 length_(0), |
50 transaction_id_(EMPTY_TRANSACTION_ID) { | 51 transaction_id_(EMPTY_TRANSACTION_ID) { |
51 ASSERT(IsValidTransactionId(transaction_id_)); | 52 RTC_DCHECK(IsValidTransactionId(transaction_id_)); |
52 attrs_ = new std::vector<StunAttribute*>(); | 53 attrs_ = new std::vector<StunAttribute*>(); |
53 } | 54 } |
54 | 55 |
55 StunMessage::~StunMessage() { | 56 StunMessage::~StunMessage() { |
56 for (size_t i = 0; i < attrs_->size(); i++) | 57 for (size_t i = 0; i < attrs_->size(); i++) |
57 delete (*attrs_)[i]; | 58 delete (*attrs_)[i]; |
58 delete attrs_; | 59 delete attrs_; |
59 } | 60 } |
60 | 61 |
61 bool StunMessage::IsLegacy() const { | 62 bool StunMessage::IsLegacy() const { |
62 if (transaction_id_.size() == kStunLegacyTransactionIdLength) | 63 if (transaction_id_.size() == kStunLegacyTransactionIdLength) |
63 return true; | 64 return true; |
64 ASSERT(transaction_id_.size() == kStunTransactionIdLength); | 65 RTC_DCHECK(transaction_id_.size() == kStunTransactionIdLength); |
65 return false; | 66 return false; |
66 } | 67 } |
67 | 68 |
68 bool StunMessage::SetTransactionID(const std::string& str) { | 69 bool StunMessage::SetTransactionID(const std::string& str) { |
69 if (!IsValidTransactionId(str)) { | 70 if (!IsValidTransactionId(str)) { |
70 return false; | 71 return false; |
71 } | 72 } |
72 transaction_id_ = str; | 73 transaction_id_ = str; |
73 return true; | 74 return true; |
74 } | 75 } |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 // |0 0| STUN Message Type | Message Length | | 192 // |0 0| STUN Message Type | Message Length | |
192 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 193 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
193 rtc::SetBE16(temp_data.get() + 2, static_cast<uint16_t>(new_adjusted_len)); | 194 rtc::SetBE16(temp_data.get() + 2, static_cast<uint16_t>(new_adjusted_len)); |
194 } | 195 } |
195 | 196 |
196 char hmac[kStunMessageIntegritySize]; | 197 char hmac[kStunMessageIntegritySize]; |
197 size_t ret = rtc::ComputeHmac(rtc::DIGEST_SHA_1, | 198 size_t ret = rtc::ComputeHmac(rtc::DIGEST_SHA_1, |
198 password.c_str(), password.size(), | 199 password.c_str(), password.size(), |
199 temp_data.get(), mi_pos, | 200 temp_data.get(), mi_pos, |
200 hmac, sizeof(hmac)); | 201 hmac, sizeof(hmac)); |
201 ASSERT(ret == sizeof(hmac)); | 202 RTC_DCHECK(ret == sizeof(hmac)); |
202 if (ret != sizeof(hmac)) | 203 if (ret != sizeof(hmac)) |
203 return false; | 204 return false; |
204 | 205 |
205 // Comparing the calculated HMAC with the one present in the message. | 206 // Comparing the calculated HMAC with the one present in the message. |
206 return memcmp(data + current_pos + kStunAttributeHeaderSize, | 207 return memcmp(data + current_pos + kStunAttributeHeaderSize, |
207 hmac, | 208 hmac, |
208 sizeof(hmac)) == 0; | 209 sizeof(hmac)) == 0; |
209 } | 210 } |
210 | 211 |
211 bool StunMessage::AddMessageIntegrity(const std::string& password) { | 212 bool StunMessage::AddMessageIntegrity(const std::string& password) { |
(...skipping 14 matching lines...) Expand all Loading... |
226 if (!Write(&buf)) | 227 if (!Write(&buf)) |
227 return false; | 228 return false; |
228 | 229 |
229 int msg_len_for_hmac = static_cast<int>( | 230 int msg_len_for_hmac = static_cast<int>( |
230 buf.Length() - kStunAttributeHeaderSize - msg_integrity_attr->length()); | 231 buf.Length() - kStunAttributeHeaderSize - msg_integrity_attr->length()); |
231 char hmac[kStunMessageIntegritySize]; | 232 char hmac[kStunMessageIntegritySize]; |
232 size_t ret = rtc::ComputeHmac(rtc::DIGEST_SHA_1, | 233 size_t ret = rtc::ComputeHmac(rtc::DIGEST_SHA_1, |
233 key, keylen, | 234 key, keylen, |
234 buf.Data(), msg_len_for_hmac, | 235 buf.Data(), msg_len_for_hmac, |
235 hmac, sizeof(hmac)); | 236 hmac, sizeof(hmac)); |
236 ASSERT(ret == sizeof(hmac)); | 237 RTC_DCHECK(ret == sizeof(hmac)); |
237 if (ret != sizeof(hmac)) { | 238 if (ret != sizeof(hmac)) { |
238 LOG(LS_ERROR) << "HMAC computation failed. Message-Integrity " | 239 LOG(LS_ERROR) << "HMAC computation failed. Message-Integrity " |
239 << "has dummy value."; | 240 << "has dummy value."; |
240 return false; | 241 return false; |
241 } | 242 } |
242 | 243 |
243 // Insert correct HMAC into the attribute. | 244 // Insert correct HMAC into the attribute. |
244 msg_integrity_attr->CopyBytes(hmac, sizeof(hmac)); | 245 msg_integrity_attr->CopyBytes(hmac, sizeof(hmac)); |
245 return true; | 246 return true; |
246 } | 247 } |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 if (!buf->ReadString(&transaction_id, kStunTransactionIdLength)) | 318 if (!buf->ReadString(&transaction_id, kStunTransactionIdLength)) |
318 return false; | 319 return false; |
319 | 320 |
320 uint32_t magic_cookie_int = | 321 uint32_t magic_cookie_int = |
321 *reinterpret_cast<const uint32_t*>(magic_cookie.data()); | 322 *reinterpret_cast<const uint32_t*>(magic_cookie.data()); |
322 if (rtc::NetworkToHost32(magic_cookie_int) != kStunMagicCookie) { | 323 if (rtc::NetworkToHost32(magic_cookie_int) != kStunMagicCookie) { |
323 // If magic cookie is invalid it means that the peer implements | 324 // If magic cookie is invalid it means that the peer implements |
324 // RFC3489 instead of RFC5389. | 325 // RFC3489 instead of RFC5389. |
325 transaction_id.insert(0, magic_cookie); | 326 transaction_id.insert(0, magic_cookie); |
326 } | 327 } |
327 ASSERT(IsValidTransactionId(transaction_id)); | 328 RTC_DCHECK(IsValidTransactionId(transaction_id)); |
328 transaction_id_ = transaction_id; | 329 transaction_id_ = transaction_id; |
329 | 330 |
330 if (length_ != buf->Length()) | 331 if (length_ != buf->Length()) |
331 return false; | 332 return false; |
332 | 333 |
333 attrs_->resize(0); | 334 attrs_->resize(0); |
334 | 335 |
335 size_t rest = buf->Length() - length_; | 336 size_t rest = buf->Length() - length_; |
336 while (buf->Length() > rest) { | 337 while (buf->Length() > rest) { |
337 uint16_t attr_type, attr_length; | 338 uint16_t attr_type, attr_length; |
(...skipping 12 matching lines...) Expand all Loading... |
350 if (!buf->Consume(attr_length)) | 351 if (!buf->Consume(attr_length)) |
351 return false; | 352 return false; |
352 } else { | 353 } else { |
353 if (!attr->Read(buf)) | 354 if (!attr->Read(buf)) |
354 return false; | 355 return false; |
355 // TODO(honghaiz): Change |attrs_| to be a vector of unique_ptrs. | 356 // TODO(honghaiz): Change |attrs_| to be a vector of unique_ptrs. |
356 attrs_->push_back(attr.release()); | 357 attrs_->push_back(attr.release()); |
357 } | 358 } |
358 } | 359 } |
359 | 360 |
360 ASSERT(buf->Length() == rest); | 361 RTC_DCHECK(buf->Length() == rest); |
361 return true; | 362 return true; |
362 } | 363 } |
363 | 364 |
364 bool StunMessage::Write(ByteBufferWriter* buf) const { | 365 bool StunMessage::Write(ByteBufferWriter* buf) const { |
365 buf->WriteUInt16(type_); | 366 buf->WriteUInt16(type_); |
366 buf->WriteUInt16(length_); | 367 buf->WriteUInt16(length_); |
367 if (!IsLegacy()) | 368 if (!IsLegacy()) |
368 buf->WriteUInt32(kStunMagicCookie); | 369 buf->WriteUInt32(kStunMagicCookie); |
369 buf->WriteString(transaction_id_); | 370 buf->WriteString(transaction_id_); |
370 | 371 |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
648 | 649 |
649 StunUInt32Attribute::StunUInt32Attribute(uint16_t type, uint32_t value) | 650 StunUInt32Attribute::StunUInt32Attribute(uint16_t type, uint32_t value) |
650 : StunAttribute(type, SIZE), bits_(value) { | 651 : StunAttribute(type, SIZE), bits_(value) { |
651 } | 652 } |
652 | 653 |
653 StunUInt32Attribute::StunUInt32Attribute(uint16_t type) | 654 StunUInt32Attribute::StunUInt32Attribute(uint16_t type) |
654 : StunAttribute(type, SIZE), bits_(0) { | 655 : StunAttribute(type, SIZE), bits_(0) { |
655 } | 656 } |
656 | 657 |
657 bool StunUInt32Attribute::GetBit(size_t index) const { | 658 bool StunUInt32Attribute::GetBit(size_t index) const { |
658 ASSERT(index < 32); | 659 RTC_DCHECK(index < 32); |
659 return static_cast<bool>((bits_ >> index) & 0x1); | 660 return static_cast<bool>((bits_ >> index) & 0x1); |
660 } | 661 } |
661 | 662 |
662 void StunUInt32Attribute::SetBit(size_t index, bool value) { | 663 void StunUInt32Attribute::SetBit(size_t index, bool value) { |
663 ASSERT(index < 32); | 664 RTC_DCHECK(index < 32); |
664 bits_ &= ~(1 << index); | 665 bits_ &= ~(1 << index); |
665 bits_ |= value ? (1 << index) : 0; | 666 bits_ |= value ? (1 << index) : 0; |
666 } | 667 } |
667 | 668 |
668 bool StunUInt32Attribute::Read(ByteBufferReader* buf) { | 669 bool StunUInt32Attribute::Read(ByteBufferReader* buf) { |
669 if (length() != SIZE || !buf->ReadUInt32(&bits_)) | 670 if (length() != SIZE || !buf->ReadUInt32(&bits_)) |
670 return false; | 671 return false; |
671 return true; | 672 return true; |
672 } | 673 } |
673 | 674 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
724 CopyBytes(bytes, strlen(bytes)); | 725 CopyBytes(bytes, strlen(bytes)); |
725 } | 726 } |
726 | 727 |
727 void StunByteStringAttribute::CopyBytes(const void* bytes, size_t length) { | 728 void StunByteStringAttribute::CopyBytes(const void* bytes, size_t length) { |
728 char* new_bytes = new char[length]; | 729 char* new_bytes = new char[length]; |
729 memcpy(new_bytes, bytes, length); | 730 memcpy(new_bytes, bytes, length); |
730 SetBytes(new_bytes, length); | 731 SetBytes(new_bytes, length); |
731 } | 732 } |
732 | 733 |
733 uint8_t StunByteStringAttribute::GetByte(size_t index) const { | 734 uint8_t StunByteStringAttribute::GetByte(size_t index) const { |
734 ASSERT(bytes_ != NULL); | 735 RTC_DCHECK(bytes_ != NULL); |
735 ASSERT(index < length()); | 736 RTC_DCHECK(index < length()); |
736 return static_cast<uint8_t>(bytes_[index]); | 737 return static_cast<uint8_t>(bytes_[index]); |
737 } | 738 } |
738 | 739 |
739 void StunByteStringAttribute::SetByte(size_t index, uint8_t value) { | 740 void StunByteStringAttribute::SetByte(size_t index, uint8_t value) { |
740 ASSERT(bytes_ != NULL); | 741 RTC_DCHECK(bytes_ != NULL); |
741 ASSERT(index < length()); | 742 RTC_DCHECK(index < length()); |
742 bytes_[index] = value; | 743 bytes_[index] = value; |
743 } | 744 } |
744 | 745 |
745 bool StunByteStringAttribute::Read(ByteBufferReader* buf) { | 746 bool StunByteStringAttribute::Read(ByteBufferReader* buf) { |
746 bytes_ = new char[length()]; | 747 bytes_ = new char[length()]; |
747 if (!buf->ReadBytes(bytes_, length())) { | 748 if (!buf->ReadBytes(bytes_, length())) { |
748 return false; | 749 return false; |
749 } | 750 } |
750 | 751 |
751 ConsumePadding(buf); | 752 ConsumePadding(buf); |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
914 digest, sizeof(digest)); | 915 digest, sizeof(digest)); |
915 if (size == 0) { | 916 if (size == 0) { |
916 return false; | 917 return false; |
917 } | 918 } |
918 | 919 |
919 *hash = std::string(digest, size); | 920 *hash = std::string(digest, size); |
920 return true; | 921 return true; |
921 } | 922 } |
922 | 923 |
923 } // namespace cricket | 924 } // namespace cricket |
OLD | NEW |