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