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