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