1 /*
2  * libjingle
3  * Copyright 2004 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 <string>
29 
30 #include "talk/base/bytebuffer.h"
31 #include "talk/base/gunit.h"
32 #include "talk/base/logging.h"
33 #include "talk/base/scoped_ptr.h"
34 #include "talk/base/socketaddress.h"
35 #include "talk/p2p/base/stun.h"
36 
37 namespace cricket {
38 
39 class StunTest : public ::testing::Test {
40  protected:
CheckStunHeader(const StunMessage & msg,StunMessageType expected_type,size_t expected_length)41   void CheckStunHeader(const StunMessage& msg, StunMessageType expected_type,
42                        size_t expected_length) {
43     ASSERT_EQ(expected_type, msg.type());
44     ASSERT_EQ(expected_length, msg.length());
45   }
46 
CheckStunTransactionID(const StunMessage & msg,const unsigned char * expectedID,size_t length)47   void CheckStunTransactionID(const StunMessage& msg,
48                               const unsigned char* expectedID, size_t length) {
49     ASSERT_EQ(0, std::memcmp(msg.transaction_id().c_str(),
50                              expectedID, length));
51   }
52 
CheckStunAddressAttribute(const StunAddressAttribute * addr,StunAddressFamily expected_family,int expected_port,talk_base::IPAddress expected_address)53   void CheckStunAddressAttribute(const StunAddressAttribute* addr,
54                                  StunAddressFamily expected_family,
55                                  int expected_port,
56                                  talk_base::IPAddress expected_address) {
57     ASSERT_EQ(expected_family, addr->family());
58     ASSERT_EQ(expected_port, addr->port());
59 
60     if (addr->family() == STUN_ADDRESS_IPV4) {
61       in_addr v4_address = expected_address.ipv4_address();
62       in_addr stun_address = addr->ipaddr().ipv4_address();
63       ASSERT_EQ(0, std::memcmp(&v4_address, &stun_address,
64                                sizeof(stun_address)));
65     } else if (addr->family() == STUN_ADDRESS_IPV6) {
66       in6_addr v6_address = expected_address.ipv6_address();
67       in6_addr stun_address = addr->ipaddr().ipv6_address();
68       ASSERT_EQ(0, std::memcmp(&v6_address, &stun_address,
69                                sizeof(stun_address)));
70     } else {
71       ASSERT_TRUE(addr->family() == STUN_ADDRESS_IPV6 ||
72                   addr->family() == STUN_ADDRESS_IPV4);
73     }
74   }
75 
ReadStunMessageTestCase(StunMessage * msg,const unsigned char * testcase,size_t size)76   size_t ReadStunMessageTestCase(StunMessage* msg,
77                                  const unsigned char* testcase,
78                                  size_t size) {
79     const char* input = reinterpret_cast<const char*>(testcase);
80     talk_base::ByteBuffer buf(input, size);
81     if (msg->Read(&buf)) {
82       // Returns the size the stun message should report itself as being
83       return (size - 20);
84     } else {
85       return 0;
86     }
87   }
88 };
89 
90 // Sample STUN packets with various attributes
91 // Gathered by wiresharking pjproject's pjnath test programs
92 // pjproject available at www.pjsip.org
93 
94 static const unsigned char kStunMessageWithIPv6MappedAddress[] = {
95   0x00, 0x01, 0x00, 0x18,  // message header
96   0x21, 0x12, 0xa4, 0x42,  // transaction id
97   0x29, 0x1f, 0xcd, 0x7c,
98   0xba, 0x58, 0xab, 0xd7,
99   0xf2, 0x41, 0x01, 0x00,
100   0x00, 0x01, 0x00, 0x14,  // Address type (mapped), length
101   0x00, 0x02, 0xb8, 0x81,  // family (IPv6), port
102   0x24, 0x01, 0xfa, 0x00,  // an IPv6 address
103   0x00, 0x04, 0x10, 0x00,
104   0xbe, 0x30, 0x5b, 0xff,
105   0xfe, 0xe5, 0x00, 0xc3
106 };
107 
108 static const unsigned char kStunMessageWithIPv4MappedAddress[] = {
109   0x01, 0x01, 0x00, 0x0c,   // binding response, length 12
110   0x21, 0x12, 0xa4, 0x42,   // magic cookie
111   0x29, 0x1f, 0xcd, 0x7c,   // transaction ID
112   0xba, 0x58, 0xab, 0xd7,
113   0xf2, 0x41, 0x01, 0x00,
114   0x00, 0x01, 0x00, 0x08,  // Mapped, 8 byte length
115   0x00, 0x01, 0x9d, 0xfc,  // AF_INET, unxor-ed port
116   0xac, 0x17, 0x44, 0xe6   // IPv4 address
117 };
118 
119 // Test XOR-mapped IP addresses:
120 static const unsigned char kStunMessageWithIPv6XorMappedAddress[] = {
121   0x01, 0x01, 0x00, 0x18,  // message header (binding response)
122   0x21, 0x12, 0xa4, 0x42,  // magic cookie (rfc5389)
123   0xe3, 0xa9, 0x46, 0xe1,  // transaction ID
124   0x7c, 0x00, 0xc2, 0x62,
125   0x54, 0x08, 0x01, 0x00,
126   0x00, 0x20, 0x00, 0x14,  // Address Type (XOR), length
127   0x00, 0x02, 0xcb, 0x5b,  // family, XOR-ed port
128   0x05, 0x13, 0x5e, 0x42,  // XOR-ed IPv6 address
129   0xe3, 0xad, 0x56, 0xe1,
130   0xc2, 0x30, 0x99, 0x9d,
131   0xaa, 0xed, 0x01, 0xc3
132 };
133 
134 static const unsigned char kStunMessageWithIPv4XorMappedAddress[] = {
135   0x01, 0x01, 0x00, 0x0c,  // message header (binding response)
136   0x21, 0x12, 0xa4, 0x42,  // magic cookie
137   0x29, 0x1f, 0xcd, 0x7c,  // transaction ID
138   0xba, 0x58, 0xab, 0xd7,
139   0xf2, 0x41, 0x01, 0x00,
140   0x00, 0x20, 0x00, 0x08,  // address type (xor), length
141   0x00, 0x01, 0xfc, 0xb5,  // family (AF_INET), XOR-ed port
142   0x8d, 0x05, 0xe0, 0xa4   // IPv4 address
143 };
144 
145 // ByteString Attribute (username)
146 static const unsigned char kStunMessageWithByteStringAttribute[] = {
147   0x00, 0x01, 0x00, 0x0c,
148   0x21, 0x12, 0xa4, 0x42,
149   0xe3, 0xa9, 0x46, 0xe1,
150   0x7c, 0x00, 0xc2, 0x62,
151   0x54, 0x08, 0x01, 0x00,
152   0x00, 0x06, 0x00, 0x08,  // username attribute (length 8)
153   0x61, 0x62, 0x63, 0x64,  // abcdefgh
154   0x65, 0x66, 0x67, 0x68
155 };
156 
157 // Message with an unknown but comprehensible optional attribute.
158 // Parsing should succeed despite this unknown attribute.
159 static const unsigned char kStunMessageWithUnknownAttribute[] = {
160   0x00, 0x01, 0x00, 0x14,
161   0x21, 0x12, 0xa4, 0x42,
162   0xe3, 0xa9, 0x46, 0xe1,
163   0x7c, 0x00, 0xc2, 0x62,
164   0x54, 0x08, 0x01, 0x00,
165   0x00, 0xaa, 0x00, 0x07,  // Unknown attribute, length 7 (needs padding!)
166   0x61, 0x62, 0x63, 0x64,  // abcdefg + padding
167   0x65, 0x66, 0x67, 0x00,
168   0x00, 0x0d, 0x00, 0x04,  // Followed by a known attribute we can
169   0x00, 0x00, 0x00, 0x0b   // check for.
170 };
171 
172 // ByteString Attribute (username) with padding byte
173 static const unsigned char kStunMessageWithPaddedByteStringAttribute[] = {
174   0x00, 0x01, 0x00, 0x08,
175   0x21, 0x12, 0xa4, 0x42,
176   0xe3, 0xa9, 0x46, 0xe1,
177   0x7c, 0x00, 0xc2, 0x62,
178   0x54, 0x08, 0x01, 0x00,
179   0x00, 0x06, 0x00, 0x03,  // username attribute (length 3)
180   0x61, 0x62, 0x63, 0xcc   // abc
181 };
182 
183 // Message with an Unknown Attributes (uint16 list) attribute.
184 static const unsigned char kStunMessageWithUInt16ListAttribute[] = {
185   0x00, 0x01, 0x00, 0x0c,
186   0x21, 0x12, 0xa4, 0x42,
187   0xe3, 0xa9, 0x46, 0xe1,
188   0x7c, 0x00, 0xc2, 0x62,
189   0x54, 0x08, 0x01, 0x00,
190   0x00, 0x0a, 0x00, 0x06,  // username attribute (length 6)
191   0x00, 0x01, 0x10, 0x00,  // three attributes plus padding
192   0xAB, 0xCU, 0xBE, 0xEF
193 };
194 
195 // Error response message (unauthorized)
196 static const unsigned char kStunMessageWithErrorAttribute[] = {
197   0x01, 0x13, 0x00, 0x14,
198   0x21, 0x12, 0xa4, 0x42,
199   0x29, 0x1f, 0xcd, 0x7c,
200   0xba, 0x58, 0xab, 0xd7,
201   0xf2, 0x41, 0x01, 0x00,
202   0x00, 0x09, 0x00, 0x10,
203   0x00, 0x00, 0x04, 0x01,
204   0x55, 0x6e, 0x61, 0x75,
205   0x74, 0x68, 0x6f, 0x72,
206   0x69, 0x7a, 0x65, 0x64
207 };
208 
209 // Message with an address attribute with an unknown address family,
210 // and a byte string attribute. Check that we quit reading after the
211 // bogus address family and don't read the username attribute.
212 static const unsigned char kStunMessageWithInvalidAddressFamily[] = {
213   0x01, 0x01, 0x00, 0x18,   // binding response, length 24
214   0x21, 0x12, 0xa4, 0x42,   // magic cookie
215   0x29, 0x1f, 0xcd, 0x7c,   // transaction ID
216   0xba, 0x58, 0xab, 0xd7,
217   0xf2, 0x41, 0x01, 0x00,
218   0x00, 0x01, 0x00, 0x08,  // Mapped address, 4 byte length
219   0x00, 0x09, 0xfe, 0xed,  // Bogus address family (port unimportant).
220   0xac, 0x17, 0x44, 0xe6,  // Should be skipped.
221   0x00, 0x06, 0x00, 0x08,  // Username attribute (length 8)
222   0x61, 0x62, 0x63, 0x64,  // abcdefgh
223   0x65, 0x66, 0x67, 0x68
224 };
225 
226 // Message with an address attribute with an invalid address length.
227 // Should fail to be read.
228 static const unsigned char kStunMessageWithInvalidAddressLength[] = {
229   0x01, 0x01, 0x00, 0x18,   // binding response, length 24
230   0x21, 0x12, 0xa4, 0x42,   // magic cookie
231   0x29, 0x1f, 0xcd, 0x7c,   // transaction ID
232   0xba, 0x58, 0xab, 0xd7,
233   0xf2, 0x41, 0x01, 0x00,
234   0x00, 0x01, 0x00, 0x0c,  // Mapped address, 12 byte length
235   0x00, 0x01, 0xfe, 0xed,  // Claims to be AF_INET.
236   0xac, 0x17, 0x44, 0xe6,
237   0x00, 0x06, 0x00, 0x08
238 };
239 
240 // Sample messages with an invalid length Field
241 
242 // The actual length in bytes of the invalid messages (including STUN header)
243 static const int kRealLengthOfInvalidLengthTestCases = 32;
244 
245 static const unsigned char kStunMessageWithZeroLength[] = {
246   0x00, 0x01, 0x00, 0x00,  // length of 0 (last 2 bytes)
247   0x21, 0x12, 0xA4, 0x42,  // magic cookie
248   '0', '1', '2', '3',      // transaction id
249   '4', '5', '6', '7',
250   '8', '9', 'a', 'b',
251   0x00, 0x20, 0x00, 0x08,  // xor mapped address
252   0x00, 0x01, 0x21, 0x1F,
253   0x21, 0x12, 0xA4, 0x53,
254 };
255 
256 static const unsigned char kStunMessageWithExcessLength[] = {
257   0x00, 0x01, 0x00, 0x55,  // length of 85
258   0x21, 0x12, 0xA4, 0x42,  // magic cookie
259   '0', '1', '2', '3',      // transaction id
260   '4', '5', '6', '7',
261   '8', '9', 'a', 'b',
262   0x00, 0x20, 0x00, 0x08,  // xor mapped address
263   0x00, 0x01, 0x21, 0x1F,
264   0x21, 0x12, 0xA4, 0x53,
265 };
266 
267 static const unsigned char kStunMessageWithSmallLength[] = {
268   0x00, 0x01, 0x00, 0x03,  // length of 3
269   0x21, 0x12, 0xA4, 0x42,  // magic cookie
270   '0', '1', '2', '3',      // transaction id
271   '4', '5', '6', '7',
272   '8', '9', 'a', 'b',
273   0x00, 0x20, 0x00, 0x08,  // xor mapped address
274   0x00, 0x01, 0x21, 0x1F,
275   0x21, 0x12, 0xA4, 0x53,
276 };
277 
278 // Legacy STUN tests.
279 // Included for completeness, but it's not recommended to change these.
280 static const unsigned char kStunMessageWithManyAttributes[] = {
281   0x00, 0x01, 0x00, 136,   // message header
282   0x21, 0x12, 0xA4, 0x42,  // magic cookie
283   '0', '1', '2', '3',      // transaction id
284   '4', '5', '6', '7',
285   '8', '9', 'a', 'b',
286   0x00, 0x01, 0x00, 8,     // mapped address
287   0x00, 0x01, 0x00, 13,
288   0x00, 0x00, 0x00, 17,
289   0x00, 0x06, 0x00, 12,    // username
290   'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
291   0x00, 0x08, 0x00, 20,    // message integrity
292   'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
293   'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
294   0x00, 0x09, 0x00, 12,    // error code
295   0x00, 0x00, 2, 10,
296   'f', 'o', 'o', ' ', 'b', 'a', 'r', '!',
297   0x00, 0x0a, 0x00, 4,     // unknown attributes
298   0x00, 0x01, 0x00, 0x02,
299   0x00, 0x0d, 0x00, 4,     // lifetime
300   0x00, 0x00, 0x00, 11,
301   0x00, 0x0f, 0x00, 4,     // magic cookie
302   0x72, 0xc6, 0x4b, 0xc6,
303   0x00, 0x10, 0x00, 4,     // bandwidth
304   0x00, 0x00, 0x00, 6,
305   0x00, 0x11, 0x00, 8,     // destination address
306   0x00, 0x01, 0x00, 13,
307   0x00, 0x00, 0x00, 17,
308   0x00, 0x12, 0x00, 8,     // source address 2
309   0x00, 0x01, 0x00, 13,
310   0x00, 0x00, 0x00, 17,
311   0x00, 0x13, 0x00, 7,     // data
312   'a', 'b', 'c', 'd', 'e', 'f', 'g', 0  // DATA must be padded per rfc5766.
313 };
314 
315 // RFC5769 Test Vectors
316 // Software name:  "STUN test client" (without quotes)
317 // Username:  "evtj:h6vY" (without quotes)
318 // Password:  "VOkJxbRl1RmTxUk/WvJxBt" (without quotes)
319 static const char kRfc5769SampleMsgPassword[] = "VOkJxbRl1RmTxUk/WvJxBt";
320 static const unsigned char kRfc5769SampleRequest[] = {
321   0x00, 0x01, 0x00, 0x58,   //     Request type and message length
322   0x21, 0x12, 0xa4, 0x42,   //  Magic cookie
323   0xb7, 0xe7, 0xa7, 0x01,   // }
324   0xbc, 0x34, 0xd6, 0x86,   // }  Transaction ID
325   0xfa, 0x87, 0xdf, 0xae,   // }
326   0x80, 0x22, 0x00, 0x10,   // SOFTWARE attribute header
327   0x53, 0x54, 0x55, 0x4e,   // }
328   0x20, 0x74, 0x65, 0x73,   // }  User-agent...
329   0x74, 0x20, 0x63, 0x6c,   // }  ...name
330   0x69, 0x65, 0x6e, 0x74,   // }
331   0x00, 0x24, 0x00, 0x04,   //   PRIORITY attribute header
332   0x6e, 0x00, 0x01, 0xff,   //   ICE priority value
333   0x80, 0x29, 0x00, 0x08,   //   ICE-CONTROLLED attribute header
334   0x93, 0x2f, 0xf9, 0xb1,   // }  Pseudo-random tie breaker...
335   0x51, 0x26, 0x3b, 0x36,   // }   ...for ICE control
336   0x00, 0x06, 0x00, 0x09,   //   USERNAME attribute header
337   0x65, 0x76, 0x74, 0x6a,   // }
338   0x3a, 0x68, 0x36, 0x76,   // }  Username (9 bytes) and padding (3 bytes)
339   0x59, 0x20, 0x20, 0x20,   // }
340   0x00, 0x08, 0x00, 0x14,   //   MESSAGE-INTEGRITY attribute header
341   0x9a, 0xea, 0xa7, 0x0c,   // }
342   0xbf, 0xd8, 0xcb, 0x56,   // }
343   0x78, 0x1e, 0xf2, 0xb5,   // }  HMAC-SHA1 fingerprint
344   0xb2, 0xd3, 0xf2, 0x49,   // }
345   0xc1, 0xb5, 0x71, 0xa2,   // }
346   0x80, 0x28, 0x00, 0x04,   //   FINGERPRINT attribute header
347   0xe5, 0x7a, 0x3b, 0xcf    //   CRC32 fingerprint
348 };
349 
350 static const unsigned char kRfc5769SampleResponse[] = {
351   0x01, 0x01, 0x00, 0x3c,  //   Response type and message length
352   0x21, 0x12, 0xa4, 0x42,  //   Magic cookie
353   0xb7, 0xe7, 0xa7, 0x01,  // }
354   0xbc, 0x34, 0xd6, 0x86,  // }  Transaction ID
355   0xfa, 0x87, 0xdf, 0xae,  // }
356   0x80, 0x22, 0x00, 0x0b,  //  SOFTWARE attribute header
357   0x74, 0x65, 0x73, 0x74,  // }
358   0x20, 0x76, 0x65, 0x63,  // }  UTF-8 server name
359   0x74, 0x6f, 0x72, 0x20,  // }
360   0x00, 0x20, 0x00, 0x08,  //   XOR-MAPPED-ADDRESS attribute header
361   0x00, 0x01, 0xa1, 0x47,  //   Address family (IPv4) and xor'd mapped port
362   0xe1, 0x12, 0xa6, 0x43,  //   Xor'd mapped IPv4 address
363   0x00, 0x08, 0x00, 0x14,  //   MESSAGE-INTEGRITY attribute header
364   0x2b, 0x91, 0xf5, 0x99,  // }
365   0xfd, 0x9e, 0x90, 0xc3,  // }
366   0x8c, 0x74, 0x89, 0xf9,  // }  HMAC-SHA1 fingerprint
367   0x2a, 0xf9, 0xba, 0x53,  // }
368   0xf0, 0x6b, 0xe7, 0xd7,  // }
369   0x80, 0x28, 0x00, 0x04,  //   FINGERPRINT attribute header
370   0xc0, 0x7d, 0x4c, 0x96   //   CRC32 fingerprint
371 };
372 
373 static const unsigned char kRfc5769SampleIPv6Response[] = {
374   0x01, 0x01, 0x00, 0x48,   //  Response type and message length
375   0x21, 0x12, 0xa4, 0x42,   //  Magic cookie
376   0xb7, 0xe7, 0xa7, 0x01,   // }
377   0xbc, 0x34, 0xd6, 0x86,   // }  Transaction ID
378   0xfa, 0x87, 0xdf, 0xae,   // }
379   0x80, 0x22, 0x00, 0x0b,   //   SOFTWARE attribute header
380   0x74, 0x65, 0x73, 0x74,   // }
381   0x20, 0x76, 0x65, 0x63,   // }  UTF-8 server name
382   0x74, 0x6f, 0x72, 0x20,   // }
383   0x00, 0x20, 0x00, 0x14,   //   XOR-MAPPED-ADDRESS attribute header
384   0x00, 0x02, 0xa1, 0x47,   //  Address family (IPv6) and xor'd mapped port.
385   0x01, 0x13, 0xa9, 0xfa,   // }
386   0xa5, 0xd3, 0xf1, 0x79,   // }  Xor'd mapped IPv6 address
387   0xbc, 0x25, 0xf4, 0xb5,   // }
388   0xbe, 0xd2, 0xb9, 0xd9,   // }
389   0x00, 0x08, 0x00, 0x14,   //   MESSAGE-INTEGRITY attribute header
390   0xa3, 0x82, 0x95, 0x4e,   // }
391   0x4b, 0xe6, 0x7b, 0xf1,   // }
392   0x17, 0x84, 0xc9, 0x7c,   // }  HMAC-SHA1 fingerprint
393   0x82, 0x92, 0xc2, 0x75,   // }
394   0xbf, 0xe3, 0xed, 0x41,   // }
395   0x80, 0x28, 0x00, 0x04,   //   FINGERPRINT attribute header
396   0xc8, 0xfb, 0x0b, 0x4c    //   CRC32 fingerprint
397 };
398 
399 // Length parameter is changed to 0x38 from 0x58.
400 // AddMessageIntegrity will add MI information and update the length param
401 // accordingly.
402 static const unsigned char kRfc5769RequestWithoutMI[] = {
403   0x00, 0x01, 0x00, 0x38,   //     Request type and message length
404   0x21, 0x12, 0xa4, 0x42,   // Magic cookie
405   0xb7, 0xe7, 0xa7, 0x01,   // }
406   0xbc, 0x34, 0xd6, 0x86,   // }  Transaction ID
407   0xfa, 0x87, 0xdf, 0xae,   // }
408   0x80, 0x22, 0x00, 0x10,   // SOFTWARE attribute header
409   0x53, 0x54, 0x55, 0x4e,   // }
410   0x20, 0x74, 0x65, 0x73,   // }  User-agent...
411   0x74, 0x20, 0x63, 0x6c,   // }  ...name
412   0x69, 0x65, 0x6e, 0x74,   // }
413   0x00, 0x24, 0x00, 0x04,   //   PRIORITY attribute header
414   0x6e, 0x00, 0x01, 0xff,   //   ICE priority value
415   0x80, 0x29, 0x00, 0x08,   //   ICE-CONTROLLED attribute header
416   0x93, 0x2f, 0xf9, 0xb1,   // }  Pseudo-random tie breaker...
417   0x51, 0x26, 0x3b, 0x36,   // }   ...for ICE control
418   0x00, 0x06, 0x00, 0x09,   //   USERNAME attribute header
419   0x65, 0x76, 0x74, 0x6a,   // }
420   0x3a, 0x68, 0x36, 0x76,   // }  Username (9 bytes) and padding (3 bytes)
421   0x59, 0x20, 0x20, 0x20    // }
422 };
423 
424 // This HMAC differs from the RFC 5769 SampleRequest message. This differs
425 // because spec uses 0x20 for the padding where as our implementation uses 0.
426 static const unsigned char kCalculatedHmac1[] = {
427   0x79, 0x07, 0xc2, 0xd2,   // }
428   0xed, 0xbf, 0xea, 0x48,   // }
429   0x0e, 0x4c, 0x76, 0xd8,   // }  HMAC-SHA1 fingerprint
430   0x29, 0x62, 0xd5, 0xc3,   // }
431   0x74, 0x2a, 0xf9, 0xe3    // }
432 };
433 
434 static const unsigned char kRfc5769SampleResponseWithoutMI[] = {
435   0x01, 0x01, 0x00, 0x1c,  //   Response type and message length
436   0x21, 0x12, 0xa4, 0x42,  //   Magic cookie
437   0xb7, 0xe7, 0xa7, 0x01,  // }
438   0xbc, 0x34, 0xd6, 0x86,  // }  Transaction ID
439   0xfa, 0x87, 0xdf, 0xae,  // }
440   0x80, 0x22, 0x00, 0x0b,  //  SOFTWARE attribute header
441   0x74, 0x65, 0x73, 0x74,  // }
442   0x20, 0x76, 0x65, 0x63,  // }  UTF-8 server name
443   0x74, 0x6f, 0x72, 0x20,  // }
444   0x00, 0x20, 0x00, 0x08,  //   XOR-MAPPED-ADDRESS attribute header
445   0x00, 0x01, 0xa1, 0x47,  //   Address family (IPv4) and xor'd mapped port
446   0xe1, 0x12, 0xa6, 0x43  //   Xor'd mapped IPv4 address
447 };
448 
449 // This HMAC differs from the RFC 5769 SampleResponse message. This differs
450 // because spec uses 0x20 for the padding where as our implementation uses 0.
451 static const unsigned char kCalculatedHmac2[] = {
452   0x5d, 0x6b, 0x58, 0xbe,  // }
453   0xad, 0x94, 0xe0, 0x7e,  // }
454   0xef, 0x0d, 0xfc, 0x12,  // }  HMAC-SHA1 fingerprint
455   0x82, 0xa2, 0xbd, 0x08,  // }
456   0x43, 0x14, 0x10, 0x28   // }
457 };
458 
459 // RTCP packet, for testing we correctly ignore non stun packet types.
460 // V=2, P=false, RC=0, Type=200, Len=6, Sender-SSRC=85, etc
461 static const unsigned char kRtcpPacket[] = {
462   0x80, 0xc8, 0x00, 0x06, 0x00, 0x00, 0x00, 0x55,
463   0xce, 0xa5, 0x18, 0x3a, 0x39, 0xcc, 0x7d, 0x09,
464   0x23, 0xed, 0x19, 0x07, 0x00, 0x00, 0x01, 0x56,
465   0x00, 0x03, 0x73, 0x50,
466 };
467 
468 // A transaction ID without the 'magic cookie' portion
469 // pjnat's test programs use this transaction ID a lot.
470 const unsigned char kTestTransactionId1[] = { 0x029, 0x01f, 0x0cd, 0x07c,
471                                               0x0ba, 0x058, 0x0ab, 0x0d7,
472                                               0x0f2, 0x041, 0x001, 0x000 };
473 
474 // They use this one sometimes too.
475 const unsigned char kTestTransactionId2[] = { 0x0e3, 0x0a9, 0x046, 0x0e1,
476                                               0x07c, 0x000, 0x0c2, 0x062,
477                                               0x054, 0x008, 0x001, 0x000 };
478 
479 const in6_addr kIPv6TestAddress1 = { { { 0x24, 0x01, 0xfa, 0x00,
480                                          0x00, 0x04, 0x10, 0x00,
481                                          0xbe, 0x30, 0x5b, 0xff,
482                                          0xfe, 0xe5, 0x00, 0xc3 } } };
483 const in6_addr kIPv6TestAddress2 = { { { 0x24, 0x01, 0xfa, 0x00,
484                                          0x00, 0x04, 0x10, 0x12,
485                                          0x06, 0x0c, 0xce, 0xff,
486                                          0xfe, 0x1f, 0x61, 0xa4 } } };
487 
488 // This is kIPv6TestAddress1 xor-ed with kTestTransactionID2.
489 const in6_addr kIPv6XoredTestAddress = { { { 0x05, 0x13, 0x5e, 0x42,
490                                              0xe3, 0xad, 0x56, 0xe1,
491                                              0xc2, 0x30, 0x99, 0x9d,
492                                              0xaa, 0xed, 0x01, 0xc3 } } };
493 
494 #ifdef POSIX
495 const in_addr kIPv4TestAddress1 =  { 0xe64417ac };
496 // This is kIPv4TestAddress xored with the STUN magic cookie.
497 const in_addr kIPv4XoredTestAddress = { 0x8d05e0a4 };
498 #elif defined WIN32
499 // Windows in_addr has a union with a uchar[] array first.
500 const in_addr kIPv4XoredTestAddress = { { 0x8d, 0x05, 0xe0, 0xa4 } };
501 const in_addr kIPv4TestAddress1 =  { { 0x0ac, 0x017, 0x044, 0x0e6 } };
502 #endif
503 const char kTestUserName1[] = "abcdefgh";
504 const char kTestUserName2[] = "abc";
505 const char kTestErrorReason[] = "Unauthorized";
506 const int kTestErrorClass = 4;
507 const int kTestErrorNumber = 1;
508 
509 const int kTestMessagePort1 = 59977;
510 const int kTestMessagePort2 = 47233;
511 const int kTestMessagePort3 = 56743;
512 const int kTestMessagePort4 = 40444;
513 
514 #define ReadStunMessage(X, Y) ReadStunMessageTestCase(X, Y, sizeof(Y));
515 
TEST_F(StunTest,ReadMessageWithIPv4AddressAttribute)516 TEST_F(StunTest, ReadMessageWithIPv4AddressAttribute) {
517   StunMessage msg;
518   size_t size = ReadStunMessage(&msg, kStunMessageWithIPv4MappedAddress);
519   CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
520   CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
521 
522   const StunAddressAttribute* addr = msg.GetAddress(STUN_ATTR_MAPPED_ADDRESS);
523   talk_base::IPAddress test_address(kIPv4TestAddress1);
524   CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV4,
525                             kTestMessagePort4, test_address);
526 }
527 
TEST_F(StunTest,ReadMessageWithIPv4XorAddressAttribute)528 TEST_F(StunTest, ReadMessageWithIPv4XorAddressAttribute) {
529   StunMessage msg;
530   StunMessage msg2;
531   size_t size = ReadStunMessage(&msg, kStunMessageWithIPv4XorMappedAddress);
532   CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
533   CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
534 
535   const StunAddressAttribute* addr =
536       msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
537   talk_base::IPAddress test_address(kIPv4TestAddress1);
538   CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV4,
539                             kTestMessagePort3, test_address);
540 }
541 
TEST_F(StunTest,ReadMessageWithIPv6AddressAttribute)542 TEST_F(StunTest, ReadMessageWithIPv6AddressAttribute) {
543   StunMessage msg;
544   size_t size = ReadStunMessage(&msg, kStunMessageWithIPv6MappedAddress);
545   CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
546   CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
547 
548   talk_base::IPAddress test_address(kIPv6TestAddress1);
549 
550   const StunAddressAttribute* addr = msg.GetAddress(STUN_ATTR_MAPPED_ADDRESS);
551   CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV6,
552                             kTestMessagePort2, test_address);
553 }
554 
TEST_F(StunTest,ReadMessageWithInvalidAddressAttribute)555 TEST_F(StunTest, ReadMessageWithInvalidAddressAttribute) {
556   StunMessage msg;
557   size_t size = ReadStunMessage(&msg, kStunMessageWithIPv6MappedAddress);
558   CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
559   CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
560 
561   talk_base::IPAddress test_address(kIPv6TestAddress1);
562 
563   const StunAddressAttribute* addr = msg.GetAddress(STUN_ATTR_MAPPED_ADDRESS);
564   CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV6,
565                             kTestMessagePort2, test_address);
566 }
567 
TEST_F(StunTest,ReadMessageWithIPv6XorAddressAttribute)568 TEST_F(StunTest, ReadMessageWithIPv6XorAddressAttribute) {
569   StunMessage msg;
570   size_t size = ReadStunMessage(&msg, kStunMessageWithIPv6XorMappedAddress);
571 
572   talk_base::IPAddress test_address(kIPv6TestAddress1);
573 
574   CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
575   CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength);
576 
577   const StunAddressAttribute* addr =
578       msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
579   CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV6,
580                             kTestMessagePort1, test_address);
581 }
582 
TEST_F(StunTest,SetIPv6XorAddressAttributeOwner)583 TEST_F(StunTest, SetIPv6XorAddressAttributeOwner) {
584   StunMessage msg;
585   StunMessage msg2;
586   size_t size = ReadStunMessage(&msg, kStunMessageWithIPv6XorMappedAddress);
587 
588   talk_base::IPAddress test_address(kIPv6TestAddress1);
589 
590   CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
591   CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength);
592 
593   const StunAddressAttribute* addr =
594       msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
595   CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV6,
596                             kTestMessagePort1, test_address);
597 
598   // Owner with a different transaction ID.
599   msg2.SetTransactionID("ABCDABCDABCD");
600   StunXorAddressAttribute addr2(STUN_ATTR_XOR_MAPPED_ADDRESS, 20);
601   addr2.SetIP(addr->ipaddr());
602   addr2.SetPort(addr->port());
603   addr2.SetOwner(&msg2);
604   // The internal IP address shouldn't change.
605   ASSERT_EQ(addr2.ipaddr(), addr->ipaddr());
606 
607   talk_base::ByteBuffer correct_buf;
608   talk_base::ByteBuffer wrong_buf;
609   addr->Write(&correct_buf);
610   addr2.Write(&wrong_buf);
611   // But when written out, the buffers should look different.
612   ASSERT_NE(0, std::memcmp(correct_buf.Data(),
613                            wrong_buf.Data(),
614                            wrong_buf.Length()));
615   // And when reading a known good value, the address should be wrong
616   addr2.Read(&correct_buf);
617   ASSERT_NE(addr->ipaddr(), addr2.ipaddr());
618   addr2.SetIP(addr->ipaddr());
619   addr2.SetPort(addr->port());
620   // Try writing with no owner at all. Should write 4 bytes (1 byte reserved,
621   // 2 bytes port, 1 byte address family, 0 bytes address). This is an invalid
622   // but well-formed address attribute.
623   addr2.SetOwner(NULL);
624   ASSERT_EQ(addr2.ipaddr(), addr->ipaddr());
625   wrong_buf.Shift(wrong_buf.Length());
626   addr2.Write(&wrong_buf);
627   ASSERT_EQ(4U, wrong_buf.Length());
628   ASSERT_NE(wrong_buf.Length(), correct_buf.Length());
629   ASSERT_NE(0, std::memcmp(correct_buf.Data(),
630                            wrong_buf.Data(),
631                            wrong_buf.Length()));
632 }
633 
TEST_F(StunTest,SetIPv4XorAddressAttributeOwner)634 TEST_F(StunTest, SetIPv4XorAddressAttributeOwner) {
635   // Unlike the IPv6XorAddressAttributeOwner test, IPv4 XOR address attributes
636   // should _not_ be affected by a change in owner. IPv4 XOR address uses the
637   // magic cookie value which is fixed.
638   StunMessage msg;
639   StunMessage msg2;
640   size_t size = ReadStunMessage(&msg, kStunMessageWithIPv4XorMappedAddress);
641 
642   talk_base::IPAddress test_address(kIPv4TestAddress1);
643 
644   CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
645   CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
646 
647   const StunAddressAttribute* addr =
648       msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
649   CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV4,
650                             kTestMessagePort3, test_address);
651 
652   // Owner with a different transaction ID.
653   msg2.SetTransactionID("ABCDABCDABCD");
654   StunXorAddressAttribute addr2(STUN_ATTR_XOR_MAPPED_ADDRESS, 20);
655   addr2.SetIP(addr->ipaddr());
656   addr2.SetPort(addr->port());
657   addr2.SetOwner(&msg2);
658   // The internal IP address shouldn't change.
659   ASSERT_EQ(addr2.ipaddr(), addr->ipaddr());
660 
661   talk_base::ByteBuffer correct_buf;
662   talk_base::ByteBuffer wrong_buf;
663   addr->Write(&correct_buf);
664   addr2.Write(&wrong_buf);
665   // The same address data should be written.
666   ASSERT_EQ(0, std::memcmp(correct_buf.Data(),
667                            wrong_buf.Data(),
668                            wrong_buf.Length()));
669   // And an attribute should be able to un-XOR an address belonging to a message
670   // with a different transaction ID.
671   addr2.Read(&correct_buf);
672   ASSERT_EQ(addr->ipaddr(), addr2.ipaddr());
673 
674   // However, no owner is still an error. Write 4 bytes and a 0 length address.
675   addr2.SetOwner(NULL);
676   ASSERT_EQ(addr2.ipaddr(), addr->ipaddr());
677   wrong_buf.Shift(wrong_buf.Length());
678   addr2.Write(&wrong_buf);
679   ASSERT_NE(wrong_buf.Length(), correct_buf.Length());
680   ASSERT_NE(0, std::memcmp(correct_buf.Data(),
681                            wrong_buf.Data(),
682                            wrong_buf.Length()));
683 }
684 
TEST_F(StunTest,CreateIPv6AddressAttribute)685 TEST_F(StunTest, CreateIPv6AddressAttribute) {
686   talk_base::IPAddress test_ip(kIPv6TestAddress2);
687 
688   StunAddressAttribute* addr =
689       StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
690   talk_base::SocketAddress test_addr(test_ip, kTestMessagePort2);
691   addr->SetAddress(test_addr);
692 
693   CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV6,
694                             kTestMessagePort2, test_ip);
695   delete addr;
696 }
697 
TEST_F(StunTest,CreateIPv4AddressAttribute)698 TEST_F(StunTest, CreateIPv4AddressAttribute) {
699   struct in_addr test_in_addr;
700   test_in_addr.s_addr = 0xBEB0B0BE;
701   talk_base::IPAddress test_ip(test_in_addr);
702 
703   StunAddressAttribute* addr =
704       StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
705   talk_base::SocketAddress test_addr(test_ip, kTestMessagePort2);
706   addr->SetAddress(test_addr);
707 
708   CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV4,
709                             kTestMessagePort2, test_ip);
710   delete addr;
711 }
712 
TEST_F(StunTest,WriteMessageWithIPv6AddressAttribute)713 TEST_F(StunTest, WriteMessageWithIPv6AddressAttribute) {
714   StunMessage msg;
715   size_t size = sizeof(kStunMessageWithIPv6MappedAddress);
716 
717   talk_base::IPAddress test_ip(kIPv6TestAddress1);
718 
719   msg.SetType(STUN_BINDING_REQUEST);
720   msg.SetTransactionID(
721       std::string(reinterpret_cast<const char*>(kTestTransactionId1),
722                   kStunTransactionIdLength));
723   CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
724 
725   StunAddressAttribute* addr =
726       StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
727   talk_base::SocketAddress test_addr(test_ip, kTestMessagePort2);
728   addr->SetAddress(test_addr);
729   msg.AddAttribute(addr);
730 
731   CheckStunHeader(msg, STUN_BINDING_REQUEST, (size - 20));
732 
733   talk_base::ByteBuffer out;
734   msg.Write(&out);
735   ASSERT_EQ(out.Length(), sizeof(kStunMessageWithIPv6MappedAddress));
736   int len1 = out.Length();
737   std::string bytes;
738   out.ReadString(&bytes, len1);
739   ASSERT_EQ(0, std::memcmp(bytes.c_str(),
740                            kStunMessageWithIPv6MappedAddress,
741                            len1));
742 }
743 
TEST_F(StunTest,WriteMessageWithIPv4AddressAttribute)744 TEST_F(StunTest, WriteMessageWithIPv4AddressAttribute) {
745   StunMessage msg;
746   size_t size = sizeof(kStunMessageWithIPv4MappedAddress);
747 
748   talk_base::IPAddress test_ip(kIPv4TestAddress1);
749 
750   msg.SetType(STUN_BINDING_RESPONSE);
751   msg.SetTransactionID(
752       std::string(reinterpret_cast<const char*>(kTestTransactionId1),
753                   kStunTransactionIdLength));
754   CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
755 
756   StunAddressAttribute* addr =
757       StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
758   talk_base::SocketAddress test_addr(test_ip, kTestMessagePort4);
759   addr->SetAddress(test_addr);
760   msg.AddAttribute(addr);
761 
762   CheckStunHeader(msg, STUN_BINDING_RESPONSE, (size - 20));
763 
764   talk_base::ByteBuffer out;
765   msg.Write(&out);
766   ASSERT_EQ(out.Length(), sizeof(kStunMessageWithIPv4MappedAddress));
767   int len1 = out.Length();
768   std::string bytes;
769   out.ReadString(&bytes, len1);
770   ASSERT_EQ(0, std::memcmp(bytes.c_str(),
771                            kStunMessageWithIPv4MappedAddress,
772                            len1));
773 }
774 
TEST_F(StunTest,WriteMessageWithIPv6XorAddressAttribute)775 TEST_F(StunTest, WriteMessageWithIPv6XorAddressAttribute) {
776   StunMessage msg;
777   size_t size = sizeof(kStunMessageWithIPv6XorMappedAddress);
778 
779   talk_base::IPAddress test_ip(kIPv6TestAddress1);
780 
781   msg.SetType(STUN_BINDING_RESPONSE);
782   msg.SetTransactionID(
783       std::string(reinterpret_cast<const char*>(kTestTransactionId2),
784                   kStunTransactionIdLength));
785   CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength);
786 
787   StunAddressAttribute* addr =
788       StunAttribute::CreateAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
789   talk_base::SocketAddress test_addr(test_ip, kTestMessagePort1);
790   addr->SetAddress(test_addr);
791   msg.AddAttribute(addr);
792 
793   CheckStunHeader(msg, STUN_BINDING_RESPONSE, (size - 20));
794 
795   talk_base::ByteBuffer out;
796   msg.Write(&out);
797   ASSERT_EQ(out.Length(), sizeof(kStunMessageWithIPv6XorMappedAddress));
798   int len1 = out.Length();
799   std::string bytes;
800   out.ReadString(&bytes, len1);
801   ASSERT_EQ(0, std::memcmp(bytes.c_str(),
802                            kStunMessageWithIPv6XorMappedAddress,
803                            len1));
804 }
805 
TEST_F(StunTest,WriteMessageWithIPv4XoreAddressAttribute)806 TEST_F(StunTest, WriteMessageWithIPv4XoreAddressAttribute) {
807   StunMessage msg;
808   size_t size = sizeof(kStunMessageWithIPv4XorMappedAddress);
809 
810   talk_base::IPAddress test_ip(kIPv4TestAddress1);
811 
812   msg.SetType(STUN_BINDING_RESPONSE);
813   msg.SetTransactionID(
814       std::string(reinterpret_cast<const char*>(kTestTransactionId1),
815                   kStunTransactionIdLength));
816   CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
817 
818   StunAddressAttribute* addr =
819       StunAttribute::CreateAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
820   talk_base::SocketAddress test_addr(test_ip, kTestMessagePort3);
821   addr->SetAddress(test_addr);
822   msg.AddAttribute(addr);
823 
824   CheckStunHeader(msg, STUN_BINDING_RESPONSE, (size - 20));
825 
826   talk_base::ByteBuffer out;
827   msg.Write(&out);
828   ASSERT_EQ(out.Length(), sizeof(kStunMessageWithIPv4XorMappedAddress));
829   int len1 = out.Length();
830   std::string bytes;
831   out.ReadString(&bytes, len1);
832   ASSERT_EQ(0, std::memcmp(bytes.c_str(),
833                            kStunMessageWithIPv4XorMappedAddress,
834                            len1));
835 }
836 
TEST_F(StunTest,ReadByteStringAttribute)837 TEST_F(StunTest, ReadByteStringAttribute) {
838   StunMessage msg;
839   size_t size = ReadStunMessage(&msg, kStunMessageWithByteStringAttribute);
840 
841   CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
842   CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength);
843   const StunByteStringAttribute* username =
844       msg.GetByteString(STUN_ATTR_USERNAME);
845   ASSERT_EQ(0, std::memcmp(kTestUserName1, username->bytes(),
846                            username->length()));
847 }
848 
TEST_F(StunTest,ReadPaddedByteStringAttribute)849 TEST_F(StunTest, ReadPaddedByteStringAttribute) {
850   StunMessage msg;
851   size_t size = ReadStunMessage(&msg,
852                                 kStunMessageWithPaddedByteStringAttribute);
853   ASSERT_NE(0U, size);
854   CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
855   CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength);
856   const StunByteStringAttribute* username =
857       msg.GetByteString(STUN_ATTR_USERNAME);
858   ASSERT_EQ(0, std::memcmp(kTestUserName2, username->bytes(),
859                            username->length()));
860 }
861 
TEST_F(StunTest,ReadErrorCodeAttribute)862 TEST_F(StunTest, ReadErrorCodeAttribute) {
863   StunMessage msg;
864   size_t size = ReadStunMessage(&msg, kStunMessageWithErrorAttribute);
865 
866   CheckStunHeader(msg, STUN_ALLOCATE_ERROR_RESPONSE, size);
867   CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
868   const StunErrorCodeAttribute* errorcode = msg.GetErrorCode();
869   ASSERT_EQ(kTestErrorClass, errorcode->error_class());
870   ASSERT_EQ(kTestErrorNumber, errorcode->number());
871   std::string reason = errorcode->reason();
872   ASSERT_EQ(0, strcmp(reason.c_str(), kTestErrorReason));
873 }
874 
TEST_F(StunTest,ReadMessageWithAnUnknownAttribute)875 TEST_F(StunTest, ReadMessageWithAnUnknownAttribute) {
876   StunMessage msg;
877   size_t size = ReadStunMessage(&msg, kStunMessageWithUnknownAttribute);
878   CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
879 
880   // Parsing should have succeeded and there should be a lifetime attribute
881   const StunUInt32Attribute* uval = msg.GetUInt32(STUN_ATTR_LIFETIME);
882   EXPECT_TRUE(uval != NULL);
883   if (uval != NULL) {
884     EXPECT_EQ(11U, uval->value());
885   }
886 }
887 
TEST_F(StunTest,ReadMessageWithAUInt16ListAttribute)888 TEST_F(StunTest, ReadMessageWithAUInt16ListAttribute) {
889   StunMessage msg;
890   size_t size = ReadStunMessage(&msg, kStunMessageWithUInt16ListAttribute);
891   CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
892   const StunUInt16ListAttribute* types = msg.GetUnknownAttributes();
893   EXPECT_EQ(3U, types->Size());
894   EXPECT_EQ(0x1U, types->GetType(0));
895   EXPECT_EQ(0x1000U, types->GetType(1));
896   EXPECT_EQ(0xAB0CU, types->GetType(2));
897 }
898 
TEST_F(StunTest,WriteMessageWithAUInt16ListAttribute)899 TEST_F(StunTest, WriteMessageWithAUInt16ListAttribute) {
900   StunMessage msg;
901   size_t size = sizeof(kStunMessageWithUInt16ListAttribute);
902 
903   msg.SetType(STUN_BINDING_REQUEST);
904   msg.SetTransactionID(
905       std::string(reinterpret_cast<const char*>(kTestTransactionId2),
906                   kStunTransactionIdLength));
907   CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength);
908   StunUInt16ListAttribute* list = StunAttribute::CreateUnknownAttributes();
909   list->AddType(0x1U);
910   list->AddType(0x1000U);
911   list->AddType(0xAB0CU);
912   msg.AddAttribute(list);
913   CheckStunHeader(msg, STUN_BINDING_REQUEST, (size - 20));
914 
915   talk_base::ByteBuffer out;
916   msg.Write(&out);
917   ASSERT_EQ(size, out.Length());
918   // Check everything up to the padding.
919   ASSERT_EQ(0, std::memcmp(out.Data(), kStunMessageWithUInt16ListAttribute,
920                            size - 2));
921 }
922 
CheckFailureToRead(const unsigned char * testcase,size_t length)923 void CheckFailureToRead(const unsigned char* testcase, size_t length) {
924   StunMessage msg;
925   const char* input = reinterpret_cast<const char*>(testcase);
926   talk_base::ByteBuffer buf(input, length);
927   ASSERT_FALSE(msg.Read(&buf));
928 }
929 
TEST_F(StunTest,FailToReadInvalidMessages)930 TEST_F(StunTest, FailToReadInvalidMessages) {
931   CheckFailureToRead(kStunMessageWithZeroLength,
932                      kRealLengthOfInvalidLengthTestCases);
933   CheckFailureToRead(kStunMessageWithSmallLength,
934                      kRealLengthOfInvalidLengthTestCases);
935   CheckFailureToRead(kStunMessageWithExcessLength,
936                      kRealLengthOfInvalidLengthTestCases);
937 }
938 
939 #undef ReadStunMessage
940 
941 // Test that we don't care what order we set the parts of an address
TEST_F(StunTest,CreateAddressInArbitraryOrder)942 TEST_F(StunTest, CreateAddressInArbitraryOrder) {
943   StunAddressAttribute* addr =
944     StunAttribute::CreateAddress(STUN_ATTR_DESTINATION_ADDRESS);
945   // Port first
946   addr->SetPort(kTestMessagePort1);
947   addr->SetIP(talk_base::IPAddress(kIPv4TestAddress1));
948   ASSERT_EQ(kTestMessagePort1, addr->port());
949   ASSERT_EQ(talk_base::IPAddress(kIPv4TestAddress1), addr->ipaddr());
950 
951   StunAddressAttribute* addr2 =
952     StunAttribute::CreateAddress(STUN_ATTR_DESTINATION_ADDRESS);
953   // IP first
954   addr2->SetIP(talk_base::IPAddress(kIPv4TestAddress1));
955   addr2->SetPort(kTestMessagePort2);
956   ASSERT_EQ(kTestMessagePort2, addr2->port());
957   ASSERT_EQ(talk_base::IPAddress(kIPv4TestAddress1), addr2->ipaddr());
958 
959   delete addr;
960   delete addr2;
961 }
962 
963 // Legacy test bodies
DoTest(const char * input,size_t size,const char * transaction_id)964 static void DoTest(const char* input, size_t size, const char* transaction_id) {
965   StunMessage msg, msg2;
966   in_addr legacy_in_addr;
967   legacy_in_addr.s_addr = htonl(17U);
968   talk_base::IPAddress legacy_ip(legacy_in_addr);
969 
970   talk_base::ByteBuffer buf(input, size);
971   EXPECT_TRUE(msg.Read(&buf));
972 
973   EXPECT_EQ(STUN_BINDING_REQUEST, msg.type());
974   EXPECT_EQ(size - 20, msg.length());
975   EXPECT_EQ(transaction_id, msg.transaction_id());
976 
977   msg2.SetType(STUN_BINDING_REQUEST);
978   msg2.SetTransactionID(transaction_id);
979 
980   const StunAddressAttribute* addr = msg.GetAddress(STUN_ATTR_MAPPED_ADDRESS);
981   ASSERT_TRUE(addr != NULL);
982   EXPECT_EQ(1, addr->family());
983   EXPECT_EQ(13, addr->port());
984   EXPECT_EQ(legacy_ip, addr->ipaddr());
985 
986   StunAddressAttribute* addr2 =
987       StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
988   addr2->SetPort(13);
989   addr2->SetIP(legacy_ip);
990   msg2.AddAttribute(addr2);
991 
992   const StunByteStringAttribute* bytes = msg.GetByteString(STUN_ATTR_USERNAME);
993   ASSERT_TRUE(bytes != NULL);
994   EXPECT_EQ(12, bytes->length());
995   EXPECT_EQ(0, std::memcmp(bytes->bytes(), "abcdefghijkl", bytes->length()));
996 
997   StunByteStringAttribute* bytes2 =
998       StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
999   bytes2->CopyBytes("abcdefghijkl");
1000   msg2.AddAttribute(bytes2);
1001 
1002   bytes = msg.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY);
1003   ASSERT_TRUE(bytes != NULL);
1004   EXPECT_EQ(20, bytes->length());
1005   EXPECT_EQ(0, std::memcmp(bytes->bytes(),
1006                       "abcdefghijklmnopqrst",
1007                       bytes->length()));
1008 
1009   bytes2 = StunAttribute::CreateByteString(STUN_ATTR_MESSAGE_INTEGRITY);
1010   bytes2->CopyBytes("abcdefghijklmnopqrst");
1011   msg2.AddAttribute(bytes2);
1012 
1013   const StunErrorCodeAttribute* ecode = msg.GetErrorCode();
1014   ASSERT_TRUE(ecode != NULL);
1015   EXPECT_EQ(2, ecode->error_class());
1016   EXPECT_EQ(10, ecode->number());
1017   EXPECT_EQ("foo bar!", ecode->reason());
1018 
1019   StunErrorCodeAttribute* ecode2 = StunAttribute::CreateErrorCode();
1020   ecode2->SetErrorClass(2);
1021   ecode2->SetNumber(10);
1022   ecode2->SetReason("foo bar!");
1023   msg2.AddAttribute(ecode2);
1024 
1025   const StunUInt16ListAttribute* unknown = msg.GetUnknownAttributes();
1026   ASSERT_TRUE(unknown != NULL);
1027   EXPECT_EQ(2U, unknown->Size());
1028   EXPECT_EQ(1U, unknown->GetType(0));
1029   EXPECT_EQ(2U, unknown->GetType(1));
1030 
1031   StunUInt16ListAttribute* unknown2 = StunAttribute::CreateUnknownAttributes();
1032   unknown2->AddType(1);
1033   unknown2->AddType(2);
1034   msg2.AddAttribute(unknown2);
1035 
1036   const StunUInt32Attribute* uval = msg.GetUInt32(STUN_ATTR_LIFETIME);
1037   ASSERT_TRUE(uval != NULL);
1038   EXPECT_EQ(11U, uval->value());
1039 
1040   StunUInt32Attribute* uval2 = StunAttribute::CreateUInt32(STUN_ATTR_LIFETIME);
1041   uval2->SetValue(11);
1042   msg2.AddAttribute(uval2);
1043 
1044   bytes = msg.GetByteString(STUN_ATTR_MAGIC_COOKIE);
1045   ASSERT_TRUE(bytes != NULL);
1046   EXPECT_EQ(4, bytes->length());
1047   EXPECT_EQ(0, std::memcmp(bytes->bytes(), TURN_MAGIC_COOKIE_VALUE,
1048                            sizeof(TURN_MAGIC_COOKIE_VALUE)));
1049 
1050   bytes2 = StunAttribute::CreateByteString(STUN_ATTR_MAGIC_COOKIE);
1051   bytes2->CopyBytes(reinterpret_cast<const char*>(TURN_MAGIC_COOKIE_VALUE),
1052                     sizeof(TURN_MAGIC_COOKIE_VALUE));
1053   msg2.AddAttribute(bytes2);
1054 
1055   uval = msg.GetUInt32(STUN_ATTR_BANDWIDTH);
1056   ASSERT_TRUE(uval != NULL);
1057   EXPECT_EQ(6U, uval->value());
1058 
1059   uval2 = StunAttribute::CreateUInt32(STUN_ATTR_BANDWIDTH);
1060   uval2->SetValue(6);
1061   msg2.AddAttribute(uval2);
1062 
1063   addr = msg.GetAddress(STUN_ATTR_DESTINATION_ADDRESS);
1064   ASSERT_TRUE(addr != NULL);
1065   EXPECT_EQ(1, addr->family());
1066   EXPECT_EQ(13, addr->port());
1067   EXPECT_EQ(legacy_ip, addr->ipaddr());
1068 
1069   addr2 = StunAttribute::CreateAddress(STUN_ATTR_DESTINATION_ADDRESS);
1070   addr2->SetPort(13);
1071   addr2->SetIP(legacy_ip);
1072   msg2.AddAttribute(addr2);
1073 
1074   addr = msg.GetAddress(STUN_ATTR_SOURCE_ADDRESS2);
1075   ASSERT_TRUE(addr != NULL);
1076   EXPECT_EQ(1, addr->family());
1077   EXPECT_EQ(13, addr->port());
1078   EXPECT_EQ(legacy_ip, addr->ipaddr());
1079 
1080   addr2 = StunAttribute::CreateAddress(STUN_ATTR_SOURCE_ADDRESS2);
1081   addr2->SetPort(13);
1082   addr2->SetIP(legacy_ip);
1083   msg2.AddAttribute(addr2);
1084 
1085   bytes = msg.GetByteString(STUN_ATTR_DATA);
1086   ASSERT_TRUE(bytes != NULL);
1087   EXPECT_EQ(7, bytes->length());
1088   EXPECT_EQ(0, std::memcmp(bytes->bytes(), "abcdefg", bytes->length()));
1089 
1090   bytes2 = StunAttribute::CreateByteString(STUN_ATTR_DATA);
1091   bytes2->CopyBytes("abcdefg");
1092   msg2.AddAttribute(bytes2);
1093 
1094   talk_base::ByteBuffer out;
1095   msg.Write(&out);
1096   EXPECT_EQ(size, out.Length());
1097   size_t len1 = out.Length();
1098   std::string outstring;
1099   out.ReadString(&outstring, len1);
1100   EXPECT_EQ(0, std::memcmp(outstring.c_str(), input, len1));
1101 
1102   talk_base::ByteBuffer out2;
1103   msg2.Write(&out2);
1104   EXPECT_EQ(size, out2.Length());
1105   size_t len2 = out2.Length();
1106   std::string outstring2;
1107   out2.ReadString(&outstring2, len2);
1108   EXPECT_EQ(0, std::memcmp(outstring2.c_str(), input, len2));
1109 }
1110 
TEST_F(StunTest,TestStunPacket)1111 TEST_F(StunTest, TestStunPacket) {
1112   DoTest(reinterpret_cast<const char*>(kStunMessageWithManyAttributes),
1113          sizeof(kStunMessageWithManyAttributes),
1114          "0123456789ab");
1115 }
1116 
TEST_F(StunTest,TestRejectsRtcpPacket)1117 TEST_F(StunTest, TestRejectsRtcpPacket) {
1118   StunMessage msg;
1119 
1120   talk_base::ByteBuffer buf(
1121       reinterpret_cast<const char*>(kRtcpPacket), sizeof(kRtcpPacket));
1122   EXPECT_FALSE(msg.Read(&buf));
1123 }
1124 
TEST_F(StunTest,TestLegacyPacket)1125 TEST_F(StunTest, TestLegacyPacket) {
1126   // The RFC3489 packet in this test is the same as
1127   // kStunMessageWithManyAttributes, but with a different value where the
1128   // magic cookie was.
1129   talk_base::scoped_array<char>
1130       rfc3489_packet(new char[sizeof(kStunMessageWithManyAttributes)]);
1131   memcpy(rfc3489_packet.get(), kStunMessageWithManyAttributes,
1132          sizeof(kStunMessageWithManyAttributes));
1133   // Overwrites the magic cookie here.
1134   memcpy(&rfc3489_packet[4], &kStunMessageWithManyAttributes[8], 4);
1135 
1136   DoTest(reinterpret_cast<const char*>(rfc3489_packet.get()),
1137          sizeof(kStunMessageWithManyAttributes), "01230123456789ab");
1138 }
1139 
TEST_F(StunTest,TestValidateMessageIntegrity)1140 TEST_F(StunTest, TestValidateMessageIntegrity) {
1141   StunMessage msg1;
1142   talk_base::ByteBuffer buf(reinterpret_cast<const char*>(
1143       kRfc5769SampleRequest), sizeof(kRfc5769SampleRequest));
1144   EXPECT_TRUE(msg1.Read(&buf));
1145   EXPECT_TRUE(msg1.ValidateMessageIntegrity(
1146       reinterpret_cast<const char*>(kRfc5769SampleRequest),
1147       sizeof(kRfc5769SampleRequest),
1148       kRfc5769SampleMsgPassword));
1149   EXPECT_FALSE(msg1.ValidateMessageIntegrity(
1150       reinterpret_cast<const char*>(kRfc5769SampleRequest),
1151       sizeof(kRfc5769SampleRequest),
1152       "InvalidPassword"));
1153 
1154   StunMessage msg2;
1155   talk_base::ByteBuffer buf2(
1156       reinterpret_cast<const char*>(kRfc5769SampleResponse),
1157       sizeof(kRfc5769SampleResponse));
1158   EXPECT_TRUE(msg2.Read(&buf2));
1159   EXPECT_TRUE(msg2.ValidateMessageIntegrity(
1160       reinterpret_cast<const char*>(kRfc5769SampleResponse),
1161       sizeof(kRfc5769SampleResponse),
1162       kRfc5769SampleMsgPassword));
1163   EXPECT_FALSE(msg2.ValidateMessageIntegrity(
1164       reinterpret_cast<const char*>(kRfc5769SampleResponse),
1165       sizeof(kRfc5769SampleResponse),
1166       "InvalidPassword"));
1167 
1168   StunMessage msg3;
1169   talk_base::ByteBuffer buf3(
1170       reinterpret_cast<const char*>(kRfc5769SampleIPv6Response),
1171       sizeof(kRfc5769SampleIPv6Response));
1172   EXPECT_TRUE(msg3.Read(&buf3));
1173   EXPECT_TRUE(msg3.ValidateMessageIntegrity(
1174       reinterpret_cast<const char*>(kRfc5769SampleIPv6Response),
1175       sizeof(kRfc5769SampleIPv6Response),
1176       kRfc5769SampleMsgPassword));
1177   EXPECT_FALSE(msg3.ValidateMessageIntegrity(
1178       reinterpret_cast<const char*>(kRfc5769SampleIPv6Response),
1179       sizeof(kRfc5769SampleIPv6Response),
1180       "InvalidPassword"));
1181 
1182   EXPECT_FALSE(StunMessage::ValidateMessageIntegrity(
1183       reinterpret_cast<const char*>(kStunMessageWithZeroLength),
1184       sizeof(kStunMessageWithZeroLength),
1185       kRfc5769SampleMsgPassword));
1186 
1187   EXPECT_FALSE(StunMessage::ValidateMessageIntegrity(
1188       reinterpret_cast<const char*>(kStunMessageWithExcessLength),
1189       sizeof(kStunMessageWithExcessLength),
1190       kRfc5769SampleMsgPassword));
1191 
1192   EXPECT_FALSE(StunMessage::ValidateMessageIntegrity(
1193       reinterpret_cast<const char*>(kStunMessageWithSmallLength),
1194       sizeof(kStunMessageWithSmallLength),
1195       kRfc5769SampleMsgPassword));
1196 }
1197 
TEST_F(StunTest,TestAddMessageIntegrity)1198 TEST_F(StunTest, TestAddMessageIntegrity) {
1199   StunMessage msg;
1200   talk_base::ByteBuffer buf(
1201       reinterpret_cast<const char*>(kRfc5769RequestWithoutMI),
1202       sizeof(kRfc5769RequestWithoutMI));
1203   EXPECT_TRUE(msg.Read(&buf));
1204   msg.AddMessageIntegrity(kRfc5769SampleMsgPassword);
1205   const StunByteStringAttribute* mi_attr =
1206       msg.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY);
1207   EXPECT_EQ(20U, mi_attr->length());
1208   EXPECT_EQ(0, std::memcmp(
1209       mi_attr->bytes(), kCalculatedHmac1, sizeof(kCalculatedHmac1)));
1210 
1211   talk_base::ByteBuffer buf1;
1212   msg.Write(&buf1);
1213   EXPECT_TRUE(msg.ValidateMessageIntegrity(
1214         reinterpret_cast<const char*>(buf1.Data()), buf1.Length(),
1215         kRfc5769SampleMsgPassword));
1216 
1217   StunMessage msg2;
1218   talk_base::ByteBuffer buf2(
1219       reinterpret_cast<const char*>(kRfc5769SampleResponseWithoutMI),
1220       sizeof(kRfc5769SampleResponseWithoutMI));
1221   EXPECT_TRUE(msg2.Read(&buf2));
1222   msg2.AddMessageIntegrity(kRfc5769SampleMsgPassword);
1223   const StunByteStringAttribute* mi_attr2 =
1224       msg2.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY);
1225   EXPECT_EQ(20U, mi_attr2->length());
1226   EXPECT_EQ(0, std::memcmp(
1227       mi_attr2->bytes(), kCalculatedHmac2, sizeof(kCalculatedHmac2)));
1228 
1229   talk_base::ByteBuffer buf3;
1230   msg2.Write(&buf3);
1231   EXPECT_TRUE(msg2.ValidateMessageIntegrity(
1232         reinterpret_cast<const char*>(buf3.Data()), buf3.Length(),
1233         kRfc5769SampleMsgPassword));
1234 }
1235 
1236 }  // namespace cricket
1237