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