1 /*
2 mediastreamer2 library - modular sound and video processing and streaming
3 Copyright (C) 2012-2016  Belledonne Communications
4 
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18 */
19 
20 
21 #include <mediastreamer2/stun.h>
22 #include <bctoolbox/crypto.h>
23 #include <bctoolbox/port.h>
24 
25 
26 #define IANA_PROTOCOL_NUMBERS_UDP 17
27 
28 #define STUN_FLAG_CHANGE_IP   0x04
29 #define STUN_FLAG_CHANGE_PORT 0x02
30 
31 #define STUN_MESSAGE_HEADER_LENGTH  20
32 #define STUN_MAX_USERNAME_LENGTH   513
33 #define STUN_MAX_REASON_LENGTH     127
34 #define STUN_MAX_SOFTWARE_LENGTH   763 /* Length in bytes, it is supposed to be less than 128 UTF-8 characters (TODO) */
35 #define STUN_MAX_REALM_LENGTH      127
36 #define STUN_MAX_NONCE_LENGTH      127
37 
38 
39 #define STUN_STR_SETTER(field, value) \
40 	if ((field) != NULL) ms_free(field); \
41 	(field) = ((value) == NULL) ? NULL : ms_strdup(value)
42 
43 
44 #if defined(htonq)
45 #elif defined(ORTP_BIGENDIAN)
46 #define htonq(n) n
47 #define ntohq(n) n
48 #else /* little endian */
htonq(uint64_t v)49 static ORTP_INLINE uint64_t htonq(uint64_t v) {
50 	return htonl((uint32_t) (v >> 32)) | (uint64_t) htonl((uint32_t) v) << 32;
51 }
ntohq(uint64_t v)52 static ORTP_INLINE uint64_t ntohq (uint64_t v) {
53 	return ntohl((uint32_t) (v >> 32)) | (uint64_t) ntohl((uint32_t) v) << 32;
54 }
55 #endif /* little endian */
56 
57 
58 
59 typedef struct {
60 	char *buffer;
61 	char *ptr;
62 	char *lenptr;
63 	size_t cursize;
64 	size_t remaining;
65 } StunMessageEncoder;
66 
67 
stun_message_encoder_init(StunMessageEncoder * encoder)68 static void stun_message_encoder_init(StunMessageEncoder *encoder) {
69 	memset(encoder, 0, sizeof(StunMessageEncoder));
70 	encoder->cursize = 128;
71 	encoder->remaining = encoder->cursize;
72 	encoder->buffer = ms_malloc(encoder->cursize);
73 	encoder->ptr = encoder->buffer;
74 }
75 
stun_message_encoder_check_size(StunMessageEncoder * encoder,size_t sz)76 static void stun_message_encoder_check_size(StunMessageEncoder *encoder, size_t sz) {
77 	while (encoder->remaining < sz) {
78 		size_t offset = encoder->ptr - encoder->buffer;
79 		encoder->cursize *= 2;
80 		encoder->buffer = ms_realloc(encoder->buffer, encoder->cursize);
81 		encoder->ptr = encoder->buffer + offset;
82 		encoder->lenptr = encoder->buffer + 2; /* Update pointer to the message length */
83 		encoder->remaining = encoder->cursize - offset;
84 	}
85 }
86 
stun_message_encoder_get_message_length(const StunMessageEncoder * encoder)87 static size_t stun_message_encoder_get_message_length(const StunMessageEncoder *encoder) {
88 	return encoder->ptr - encoder->buffer;
89 }
90 
stun_message_encoder_memcpy(StunMessageEncoder * encoder,const void * src,size_t len)91 static void stun_message_encoder_memcpy(StunMessageEncoder *encoder, const void *src, size_t len) {
92 	stun_message_encoder_check_size(encoder, len);
93 	memcpy(encoder->ptr, src, len);
94 	encoder->remaining -= len;
95 	encoder->ptr += len;
96 }
97 
stun_address_xor(MSStunAddress * addr,const UInt96 * tr_id)98 static void stun_address_xor(MSStunAddress *addr, const UInt96 *tr_id) {
99 	if (addr->family == MS_STUN_ADDR_FAMILY_IPV4) {
100 		addr->ip.v4.addr ^= MS_STUN_MAGIC_COOKIE;
101 		addr->ip.v4.port ^= MS_STUN_MAGIC_COOKIE >> 16;
102 	} else if (addr->family == MS_STUN_ADDR_FAMILY_IPV6) {
103 		int i;
104 		uint32_t magic_cookie = htonl(MS_STUN_MAGIC_COOKIE);
105 		for (i = 0; i < 4; i++) {
106 			addr->ip.v6.addr.octet[i] ^= ((uint8_t *)&magic_cookie)[i];
107 		}
108 		for (i = 0; i < 12; i++) {
109 			addr->ip.v6.addr.octet[i + 4] ^= tr_id->octet[i];
110 		}
111 		addr->ip.v6.port ^= MS_STUN_MAGIC_COOKIE >> 16;
112 	}
113 }
114 
encode8(StunMessageEncoder * encoder,uint8_t data)115 static void encode8(StunMessageEncoder *encoder, uint8_t data) {
116 	stun_message_encoder_memcpy(encoder, &data, sizeof(data));
117 }
118 
encode16(StunMessageEncoder * encoder,uint16_t data)119 static void encode16(StunMessageEncoder *encoder, uint16_t data) {
120 	uint16_t ndata = htons(data);
121 	stun_message_encoder_memcpy(encoder, &ndata, sizeof(ndata));
122 }
123 
encode32(StunMessageEncoder * encoder,uint32_t data)124 static void encode32(StunMessageEncoder *encoder, uint32_t data) {
125 	uint32_t ndata = htonl(data);
126 	stun_message_encoder_memcpy(encoder, &ndata, sizeof(ndata));
127 }
128 
encode64(StunMessageEncoder * encoder,uint64_t data)129 static void encode64(StunMessageEncoder *encoder, uint64_t data) {
130 	uint64_t ndata = htonq(data);
131 	stun_message_encoder_memcpy(encoder, &ndata, sizeof(ndata));
132 }
133 
encode(StunMessageEncoder * encoder,const void * src,size_t len)134 static void encode(StunMessageEncoder *encoder, const void *src, size_t len) {
135 	stun_message_encoder_memcpy(encoder, src, len);
136 }
137 
encode_message_length(StunMessageEncoder * encoder,size_t len)138 static void encode_message_length(StunMessageEncoder *encoder, size_t len) {
139 	uint16_t ndata = htons((uint16_t)len);
140 	memcpy(encoder->lenptr, &ndata, sizeof(ndata));
141 }
142 
encode_message_header(StunMessageEncoder * encoder,uint16_t type,uint16_t method,const UInt96 * tr_id)143 static void encode_message_header(StunMessageEncoder *encoder, uint16_t type, uint16_t method, const UInt96 *tr_id) {
144 	encode16(encoder, type | method);
145 	encoder->lenptr = encoder->ptr;
146 	encode16(encoder, 0);	/* Initialize length to 0, it will be updated later */
147 	encode32(encoder, MS_STUN_MAGIC_COOKIE); /* magic cookie */
148 	encode(encoder, tr_id, sizeof(UInt96));
149 }
150 
encode_addr(StunMessageEncoder * encoder,uint16_t type,const MSStunAddress * addr)151 static void encode_addr(StunMessageEncoder *encoder, uint16_t type, const MSStunAddress *addr) {
152 	encode16(encoder, type);
153 	if (addr->family == MS_STUN_ADDR_FAMILY_IPV6) {
154 		encode16(encoder, 20);
155 	} else {
156 		encode16(encoder, 8);
157 	}
158 	encode8(encoder, 0);
159 	encode8(encoder, addr->family);
160 	if (addr->family == MS_STUN_ADDR_FAMILY_IPV6) {
161 		encode16(encoder, addr->ip.v6.port);
162 		encode(encoder, &addr->ip.v6.addr, sizeof(UInt128));
163 	} else {
164 		encode16(encoder, addr->ip.v4.port);
165 		encode32(encoder, addr->ip.v4.addr);
166 	}
167 }
168 
encode_xor_addr(StunMessageEncoder * encoder,uint16_t type,const MSStunAddress * addr,const UInt96 * tr_id)169 static void encode_xor_addr(StunMessageEncoder *encoder, uint16_t type, const MSStunAddress *addr, const UInt96 *tr_id) {
170 	MSStunAddress xor_addr = *addr;
171 	stun_address_xor(&xor_addr, tr_id);
172 	encode_addr(encoder, type, &xor_addr);
173 }
174 
encode_change_request(StunMessageEncoder * encoder,uint32_t data)175 static void encode_change_request(StunMessageEncoder *encoder, uint32_t data) {
176 	encode16(encoder, MS_STUN_ATTR_CHANGE_REQUEST);
177 	encode16(encoder, 4);
178 	encode32(encoder, data);
179 }
180 
encode_string(StunMessageEncoder * encoder,uint16_t type,const char * data,uint16_t max_length)181 static void encode_string(StunMessageEncoder *encoder, uint16_t type, const char *data, uint16_t max_length) {
182 	size_t len = strlen(data);
183 	size_t padding;
184 
185 	if (len > max_length) {
186 		len = max_length;
187 		ms_warning("STUN encoded string truncated");
188 	}
189 	padding = 4 - (len % 4);
190 	encode16(encoder, type);
191 	encode16(encoder, (uint16_t)len);
192 	encode(encoder, data, len);
193 	if (padding < 4) {
194 		size_t i;
195 		for (i = 0; i < padding; i++) encode8(encoder, 0);
196 	}
197 }
198 
encode_error_code(StunMessageEncoder * encoder,uint16_t number,const char * reason)199 static void encode_error_code(StunMessageEncoder *encoder, uint16_t number, const char *reason) {
200 	size_t reason_len = 0;
201 	size_t padding = 4 - (reason_len % 4);
202 	if (reason != NULL) reason_len = strlen(reason);
203 	encode16(encoder, MS_STUN_ATTR_ERROR_CODE);
204 	encode16(encoder, 4 + (uint16_t)reason_len);
205 	encode16(encoder, 0);
206 	encode8(encoder, number / 100);
207 	encode8(encoder, number - ((number / 100) * 100));
208 	if (reason != NULL) encode(encoder, reason, reason_len);
209 	if (padding < 4) {
210 		size_t i;
211 		for (i = 0; i < padding; i++) encode8(encoder, 0);
212 	}
213 }
214 
encode_priority(StunMessageEncoder * encoder,uint32_t priority)215 static void encode_priority(StunMessageEncoder *encoder, uint32_t priority) {
216 	encode16(encoder, MS_ICE_ATTR_PRIORITY);
217 	encode16(encoder, 4);
218 	encode32(encoder, priority);
219 }
220 
encode_use_candidate(StunMessageEncoder * encoder)221 static void encode_use_candidate(StunMessageEncoder *encoder) {
222 	encode16(encoder, MS_ICE_ATTR_USE_CANDIDATE);
223 	encode16(encoder, 0);
224 }
225 
encode_ice_control(StunMessageEncoder * encoder,uint16_t type,uint64_t value)226 static void encode_ice_control(StunMessageEncoder *encoder, uint16_t type, uint64_t value) {
227 	encode16(encoder, type);
228 	encode16(encoder, 8);
229 	encode64(encoder, value);
230 }
231 
encode_integrity(StunMessageEncoder * encoder,const char * hmac)232 static void encode_integrity(StunMessageEncoder *encoder, const char *hmac) {
233 	encode16(encoder, MS_STUN_ATTR_MESSAGE_INTEGRITY);
234 	encode16(encoder, 20);
235 	encode(encoder, hmac, 20);
236 }
237 
encode_long_term_integrity_from_ha1(StunMessageEncoder * encoder,const char * ha1_text)238 static void encode_long_term_integrity_from_ha1(StunMessageEncoder *encoder, const char *ha1_text) {
239 	char *hmac;
240 	size_t message_length = stun_message_encoder_get_message_length(encoder);
241 	encode_message_length(encoder, message_length - STUN_MESSAGE_HEADER_LENGTH + 24);
242 	hmac = ms_stun_calculate_integrity_long_term_from_ha1(encoder->buffer, message_length, ha1_text);
243 	encode_integrity(encoder, hmac);
244 	ms_free(hmac);
245 }
246 
encode_long_term_integrity(StunMessageEncoder * encoder,const char * realm,const char * username,const char * password)247 static void encode_long_term_integrity(StunMessageEncoder *encoder, const char *realm, const char *username, const char *password) {
248 	char *hmac;
249 	size_t message_length = stun_message_encoder_get_message_length(encoder);
250 	encode_message_length(encoder, message_length - STUN_MESSAGE_HEADER_LENGTH + 24);
251 	hmac = ms_stun_calculate_integrity_long_term(encoder->buffer, message_length, realm, username, password);
252 	encode_integrity(encoder, hmac);
253 	ms_free(hmac);
254 }
255 
encode_short_term_integrity(StunMessageEncoder * encoder,const char * password,bool_t dummy)256 static void encode_short_term_integrity(StunMessageEncoder *encoder, const char *password, bool_t dummy) {
257 	char *hmac;
258 	size_t message_length = stun_message_encoder_get_message_length(encoder);
259 	encode_message_length(encoder, message_length - STUN_MESSAGE_HEADER_LENGTH + 24);
260 	if (dummy) {
261 		hmac = ms_strdup("hmac-not-implemented");
262 		ms_warning("hmac not implemented by remote, using dummy integrity hash for stun message");
263 	} else {
264 		hmac = ms_stun_calculate_integrity_short_term(encoder->buffer, message_length, password);
265 	}
266 	encode_integrity(encoder, hmac);
267 	ms_free(hmac);
268 }
269 
encode_fingerprint(StunMessageEncoder * encoder)270 static void encode_fingerprint(StunMessageEncoder *encoder) {
271 	uint32_t fingerprint;
272 	size_t message_length = stun_message_encoder_get_message_length(encoder);
273 	encode_message_length(encoder, message_length - STUN_MESSAGE_HEADER_LENGTH + 8);
274 	fingerprint = ms_stun_calculate_fingerprint(encoder->buffer, message_length);
275 	encode16(encoder, MS_STUN_ATTR_FINGERPRINT);
276 	encode16(encoder, 4);
277 	fingerprint ^= 0x5354554E;
278 	encode32(encoder, fingerprint);
279 }
280 
encode_requested_transport(StunMessageEncoder * encoder,uint8_t requested_transport)281 static void encode_requested_transport(StunMessageEncoder *encoder, uint8_t requested_transport) {
282 	encode16(encoder, MS_TURN_ATTR_REQUESTED_TRANSPORT);
283 	encode16(encoder, 4);
284 	encode8(encoder, requested_transport);
285 	encode8(encoder, 0);
286 	encode16(encoder, 0);
287 }
288 
encode_requested_address_family(StunMessageEncoder * encoder,uint8_t family)289 static void encode_requested_address_family(StunMessageEncoder *encoder, uint8_t family) {
290 	encode16(encoder, MS_TURN_ATTR_REQUESTED_ADDRESS_FAMILY);
291 	encode16(encoder, 4);
292 	encode8(encoder, family);
293 	encode8(encoder, 0);
294 	encode16(encoder, 0);
295 }
296 
encode_lifetime(StunMessageEncoder * encoder,uint32_t lifetime)297 static void encode_lifetime(StunMessageEncoder *encoder, uint32_t lifetime) {
298 	encode16(encoder, MS_TURN_ATTR_LIFETIME);
299 	encode16(encoder, 4);
300 	encode32(encoder, lifetime);
301 }
302 
encode_channel_number(StunMessageEncoder * encoder,uint16_t channel_number)303 static void encode_channel_number(StunMessageEncoder *encoder, uint16_t channel_number) {
304 	encode16(encoder, MS_TURN_ATTR_CHANNEL_NUMBER);
305 	encode16(encoder, 4);
306 	encode16(encoder, channel_number);
307 	encode16(encoder, 0);
308 }
309 
encode_data(StunMessageEncoder * encoder,uint8_t * data,uint16_t datalen)310 static void encode_data(StunMessageEncoder *encoder, uint8_t *data, uint16_t datalen) {
311 	size_t padding = 4 - (datalen % 4);
312 	encode16(encoder, MS_TURN_ATTR_DATA);
313 	encode16(encoder, datalen);
314 	encode(encoder, data, datalen);
315 	if (padding < 4) {
316 		size_t i;
317 		for (i = 0; i < padding; i++) encode8(encoder, 0);
318 	}
319 }
320 
321 
322 typedef struct {
323 	const uint8_t *buffer;
324 	const uint8_t *ptr;
325 	ssize_t size;
326 	ssize_t remaining;
327 	bool_t error;
328 } StunMessageDecoder;
329 
330 
stun_message_decoder_init(StunMessageDecoder * decoder,const uint8_t * buf,ssize_t bufsize)331 static void stun_message_decoder_init(StunMessageDecoder *decoder, const uint8_t *buf, ssize_t bufsize) {
332 	decoder->buffer = decoder->ptr = buf;
333 	decoder->size = decoder->remaining = bufsize;
334 	decoder->error = FALSE;
335 }
336 
decode8(StunMessageDecoder * decoder)337 static uint8_t decode8(StunMessageDecoder *decoder) {
338 	uint8_t value = *((uint8_t *)decoder->ptr);
339 	decoder->ptr += sizeof(uint8_t);
340 	decoder->remaining -= sizeof(uint8_t);
341 	if (decoder->remaining < 0) decoder->error = TRUE;
342 	return value;
343 }
344 
decode16(StunMessageDecoder * decoder)345 static uint16_t decode16(StunMessageDecoder *decoder) {
346 	uint16_t value = ntohs(*((uint16_t *)decoder->ptr));
347 	decoder->ptr += sizeof(uint16_t);
348 	decoder->remaining -= sizeof(uint16_t);
349 	if (decoder->remaining < 0) decoder->error = TRUE;
350 	return value;
351 }
352 
decode32(StunMessageDecoder * decoder)353 static uint32_t decode32(StunMessageDecoder *decoder) {
354 	uint32_t value = ntohl(*((uint32_t *)decoder->ptr));
355 	decoder->ptr += sizeof(uint32_t);
356 	decoder->remaining -= sizeof(uint32_t);
357 	if (decoder->remaining < 0) decoder->error = TRUE;
358 	return value;
359 }
360 
decode64(StunMessageDecoder * decoder)361 static uint64_t decode64(StunMessageDecoder *decoder) {
362 	uint64_t value = ntohq(*((uint64_t *)decoder->ptr));
363 	decoder->ptr += sizeof(uint64_t);
364 	decoder->remaining -= sizeof(uint64_t);
365 	if (decoder->remaining < 0) decoder->error = TRUE;
366 	return value;
367 }
368 
decode(StunMessageDecoder * decoder,size_t len)369 static const void * decode(StunMessageDecoder *decoder, size_t len) {
370 	const void *value = decoder->ptr;
371 	decoder->ptr += len;
372 	decoder->remaining -= (ssize_t)len;
373 	if (decoder->remaining < 0) decoder->error = TRUE;
374 	return value;
375 }
376 
decode_message_header(StunMessageDecoder * decoder,MSStunMessage * msg)377 static void decode_message_header(StunMessageDecoder *decoder, MSStunMessage *msg) {
378 	uint16_t type = decode16(decoder);
379 	uint32_t magic_cookie;
380 	UInt96 *tr_id;
381 
382 	msg->type = type & 0x0110;
383 	msg->method = type & 0x3EEF;
384 	msg->length = decode16(decoder);
385 	magic_cookie = decode32(decoder);
386 	if (magic_cookie != MS_STUN_MAGIC_COOKIE) {
387 		ms_warning("STUN magic cookie is incorrect");
388 		decoder->error = TRUE;
389 		return;
390 	}
391 	tr_id = (UInt96 *)decode(decoder, sizeof(UInt96));
392 	ms_stun_message_set_tr_id(msg, *tr_id);
393 }
394 
decode_attribute_header(StunMessageDecoder * decoder,uint16_t * type,uint16_t * length)395 static void decode_attribute_header(StunMessageDecoder *decoder, uint16_t *type ,uint16_t *length) {
396 	*type = decode16(decoder);
397 	*length = decode16(decoder);
398 }
399 
decode_addr(StunMessageDecoder * decoder,uint16_t length)400 static MSStunAddress decode_addr(StunMessageDecoder *decoder, uint16_t length) {
401 	MSStunAddress stun_addr;
402 
403 	memset(&stun_addr, 0, sizeof(stun_addr));
404 	if ((length != 8) && (length != 20)) {
405 		ms_warning("STUN address attribute with wrong length");
406 		decoder->error = TRUE;
407 		goto error;
408 	}
409 
410 	decode8(decoder);
411 	stun_addr.family = decode8(decoder);
412 	if (stun_addr.family == MS_STUN_ADDR_FAMILY_IPV6) {
413 		stun_addr.ip.v6.port = decode16(decoder);
414 		memcpy(&stun_addr.ip.v6.addr, decode(decoder, sizeof(UInt128)), sizeof(UInt128));
415 	} else {
416 		stun_addr.ip.v4.port = decode16(decoder);
417 		stun_addr.ip.v4.addr = decode32(decoder);
418 	}
419 
420 error:
421 	return stun_addr;
422 }
423 
decode_xor_addr(StunMessageDecoder * decoder,uint16_t length,UInt96 tr_id)424 static MSStunAddress decode_xor_addr(StunMessageDecoder *decoder, uint16_t length, UInt96 tr_id) {
425 	MSStunAddress stun_addr = decode_addr(decoder, length);
426 	stun_address_xor(&stun_addr, &tr_id);
427 	return stun_addr;
428 }
429 
decode_change_request(StunMessageDecoder * decoder,uint16_t length)430 static uint32_t decode_change_request(StunMessageDecoder *decoder, uint16_t length) {
431 	if (length != 4) {
432 		ms_warning("STUN change address attribute with wrong length");
433 		decoder->error = TRUE;
434 		return 0;
435 	}
436 	return decode32(decoder);
437 }
438 
decode_string(StunMessageDecoder * decoder,uint16_t length,uint16_t max_length)439 static char * decode_string(StunMessageDecoder *decoder, uint16_t length, uint16_t max_length) {
440 	char *str;
441 
442 	if (length > max_length) {
443 		ms_warning("STUN string attribute too long");
444 		decoder->error = TRUE;
445 		return NULL;
446 	}
447 	str = ms_malloc(length + 1);
448 	memcpy(str, decoder->ptr, length);
449 	str[length] = '\0';
450 	decoder->ptr += length;
451 	decoder->remaining -= length;
452 	if (decoder->remaining < 0) decoder->error = TRUE;
453 	return str;
454 }
455 
decode_error_code(StunMessageDecoder * decoder,uint16_t length,char ** reason)456 static uint16_t decode_error_code(StunMessageDecoder *decoder, uint16_t length, char **reason) {
457 	uint16_t number;
458 	uint16_t reason_length;
459 	uint8_t clazz;
460 	uint8_t code;
461 
462 	if ((length < 4) || (length > (STUN_MAX_REASON_LENGTH + 4))) {
463 		ms_warning("STUN error code attribute with wrong length");
464 		decoder->error = TRUE;
465 		return 0;
466 	}
467 
468 	reason_length = length - 4;
469 	decode16(decoder);
470 	clazz = decode8(decoder);
471 	code = decode8(decoder);
472 	number = clazz * 100 + code;
473 	if (reason_length > 0) {
474 		*reason = ms_malloc(reason_length + 1);
475 		memcpy(*reason, decode(decoder, reason_length), reason_length);
476 		(*reason)[reason_length] = '\0';
477 	}
478 	return number;
479 }
480 
decode_message_integrity(StunMessageDecoder * decoder,uint16_t length)481 static char * decode_message_integrity(StunMessageDecoder *decoder, uint16_t length) {
482 	char *hmac;
483 
484 	if (length != 20) {
485 		ms_warning("STUN message integrity attribute with wrong length");
486 		decoder->error = TRUE;
487 		return NULL;
488 	}
489 	hmac = ms_malloc(21);
490 	memcpy(hmac, decode(decoder, 20), 20);
491 	hmac[20] = '\0';
492 	return hmac;
493 }
494 
decode_fingerprint(StunMessageDecoder * decoder,uint16_t length)495 static uint32_t decode_fingerprint(StunMessageDecoder *decoder, uint16_t length) {
496 	if (length != 4) {
497 		ms_warning("STUN fingerprint attribute with wrong length");
498 		decoder->error = TRUE;
499 		return 0;
500 	}
501 	return decode32(decoder);
502 }
503 
decode_priority(StunMessageDecoder * decoder,uint16_t length)504 static uint32_t decode_priority(StunMessageDecoder *decoder, uint16_t length) {
505 	if (length != 4) {
506 		ms_warning("STUN priority attribute with wrong length");
507 		decoder->error = TRUE;
508 		return 0;
509 	}
510 	return decode32(decoder);
511 }
512 
decode_ice_control(StunMessageDecoder * decoder,uint16_t length)513 static uint64_t decode_ice_control(StunMessageDecoder *decoder, uint16_t length) {
514 	if (length != 8) {
515 		ms_warning("STUN ice-controlled/ice-controlling attribute with wrong length");
516 		decoder->error = TRUE;
517 		return 0;
518 	}
519 	return decode64(decoder);
520 }
521 
decode_lifetime(StunMessageDecoder * decoder,uint16_t length)522 static uint32_t decode_lifetime(StunMessageDecoder *decoder, uint16_t length) {
523 	if (length != 4) {
524 		ms_warning("STUN lifetime attribute with wrong length");
525 		decoder->error = TRUE;
526 		return 0;
527 	}
528 	return decode32(decoder);
529 }
530 
decode_data(StunMessageDecoder * decoder,uint16_t length)531 static uint8_t * decode_data(StunMessageDecoder *decoder, uint16_t length) {
532 	uint8_t *data = ms_malloc(length);
533 	memcpy(data, decode(decoder, length), length);
534 	return data;
535 }
536 
537 
ms_stun_address_set_port(MSStunAddress * addr,uint16_t port)538 static void ms_stun_address_set_port(MSStunAddress *addr, uint16_t port) {
539 	if (addr->family == MS_STUN_ADDR_FAMILY_IPV4) {
540 		addr->ip.v4.port = port;
541 	} else if (addr->family == MS_STUN_ADDR_FAMILY_IPV6) {
542 		addr->ip.v6.port = port;
543 	}
544 }
545 
ms_compare_stun_addresses(const MSStunAddress * a1,const MSStunAddress * a2)546 bool_t ms_compare_stun_addresses(const MSStunAddress *a1, const MSStunAddress *a2) {
547 	if (a1->family != a2->family) return TRUE;
548 	if (a1->family == MS_STUN_ADDR_FAMILY_IPV4) {
549 		return !((a1->ip.v4.port == a2->ip.v4.port)
550 		&& (a1->ip.v4.addr == a2->ip.v4.addr));
551 	} else if (a1->family == MS_STUN_ADDR_FAMILY_IPV6) {
552 		return !((a1->ip.v6.port == a2->ip.v6.port)
553 		&& (memcmp(&a1->ip.v6.addr, &a2->ip.v6.addr, sizeof(UInt128)) == 0));
554 	}
555 	return TRUE;
556 }
557 
ms_stun_family_to_af(int stun_family)558 int ms_stun_family_to_af(int stun_family) {
559 	if (stun_family == MS_STUN_ADDR_FAMILY_IPV4) return AF_INET;
560 	else if (stun_family == MS_STUN_ADDR_FAMILY_IPV6) return AF_INET6;
561 	else return 0;
562 }
563 
ms_stun_address_to_sockaddr(const MSStunAddress * stun_addr,struct sockaddr * addr,socklen_t * addrlen)564 void ms_stun_address_to_sockaddr(const MSStunAddress *stun_addr, struct sockaddr *addr, socklen_t *addrlen) {
565 	if (stun_addr->family == MS_STUN_ADDR_FAMILY_IPV4) {
566 		struct sockaddr_in *addr_in = (struct sockaddr_in *)addr;
567 		addr_in->sin_family = AF_INET;
568 		addr_in->sin_port = htons(stun_addr->ip.v4.port);
569 		addr_in->sin_addr.s_addr = htonl(stun_addr->ip.v4.addr);
570 		*addrlen = sizeof(struct sockaddr_in);
571 	} else if (stun_addr->family == MS_STUN_ADDR_FAMILY_IPV6) {
572 		struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)addr;
573 		addr_in6->sin6_family = AF_INET6;
574 		addr_in6->sin6_port = htons(stun_addr->ip.v6.port);
575 		memcpy(addr_in6->sin6_addr.s6_addr, &stun_addr->ip.v6.addr, sizeof(UInt128));
576 		*addrlen = sizeof(struct sockaddr_in6);
577 	} else {
578 		memset(addr, 0, *addrlen);
579 	}
580 }
581 
ms_sockaddr_to_stun_address(const struct sockaddr * addr,MSStunAddress * stun_addr)582 void ms_sockaddr_to_stun_address(const struct sockaddr *addr, MSStunAddress *stun_addr) {
583 	if (addr->sa_family == AF_INET) {
584 		stun_addr->family = MS_STUN_ADDR_FAMILY_IPV4;
585 		stun_addr->ip.v4.port = ntohs(((const struct sockaddr_in *)addr)->sin_port);
586 		stun_addr->ip.v4.addr = ntohl(((const struct sockaddr_in *)addr)->sin_addr.s_addr);
587 	} else if (addr->sa_family == AF_INET6) {
588 		stun_addr->family = MS_STUN_ADDR_FAMILY_IPV6;
589 		stun_addr->ip.v6.port = ntohs(((const struct sockaddr_in6 *)addr)->sin6_port);
590 		memcpy(&stun_addr->ip.v6.addr, ((const struct sockaddr_in6 *)addr)->sin6_addr.s6_addr, sizeof(UInt128));
591 	} else {
592 		memset(stun_addr, 0, sizeof(MSStunAddress));
593 	}
594 }
595 
ms_ip_address_to_stun_address(int ai_family,int socktype,const char * hostname,int port)596 MSStunAddress ms_ip_address_to_stun_address(int ai_family, int socktype, const char *hostname, int port) {
597 	MSStunAddress stun_addr;
598 	struct addrinfo *res = bctbx_ip_address_to_addrinfo(ai_family, socktype, hostname, port);
599 	memset(&stun_addr, 0, sizeof(stun_addr));
600 	if (res){
601 		ms_sockaddr_to_stun_address(res->ai_addr, &stun_addr);
602 		bctbx_freeaddrinfo(res);
603 	}
604 	return stun_addr;
605 }
606 
ms_stun_address_to_ip_address(const MSStunAddress * stun_address,char * ip,size_t ip_size,int * port)607 void ms_stun_address_to_ip_address(const MSStunAddress *stun_address, char *ip, size_t ip_size, int *port) {
608 	struct sockaddr_storage addr;
609 	socklen_t addrlen = sizeof(addr);
610 	memset(&addr, 0, addrlen);
611 	ms_stun_address_to_sockaddr(stun_address, (struct sockaddr *)&addr, &addrlen);
612 	bctbx_sockaddr_to_ip_address((struct sockaddr *)&addr, addrlen, ip, ip_size, port);
613 }
614 
ms_stun_address_to_printable_ip_address(const MSStunAddress * stun_address,char * printable_ip,size_t printable_ip_size)615 void ms_stun_address_to_printable_ip_address(const MSStunAddress *stun_address, char *printable_ip, size_t printable_ip_size) {
616 	struct sockaddr_storage addr;
617 	socklen_t addrlen = sizeof(addr);
618 	memset(&addr, 0, addrlen);
619 	ms_stun_address_to_sockaddr(stun_address, (struct sockaddr *)&addr, &addrlen);
620 	bctbx_sockaddr_to_printable_ip_address((struct sockaddr *)&addr, addrlen, printable_ip, printable_ip_size);
621 }
622 
ms_stun_calculate_integrity_short_term(const char * buf,size_t bufsize,const char * key)623 char * ms_stun_calculate_integrity_short_term(const char *buf, size_t bufsize, const char *key) {
624 	char *hmac = ms_malloc(21);
625 	memset(hmac, 0, 21);
626 	/* SHA1 output length is 20 bytes, get them all */
627 	bctbx_hmacSha1((const unsigned char *)key, strlen(key), (const unsigned char *)buf, bufsize, 20, (unsigned char *)hmac);
628 	return hmac;
629 }
630 
ms_stun_calculate_integrity_long_term_from_ha1(const char * buf,size_t bufsize,const char * ha1_text)631 char * ms_stun_calculate_integrity_long_term_from_ha1(const char *buf, size_t bufsize, const char *ha1_text) {
632 	unsigned char ha1[16];
633 	unsigned int i, j;
634 	char *hmac = ms_malloc(21);
635 	memset(hmac, 0, 21);
636 	memset(ha1, 0, sizeof(ha1));
637 	for (i = 0, j = 0; (i < strlen(ha1_text)) && (j < sizeof(ha1)); i += 2, j++) {
638 		char buf[5] = { '0', 'x', ha1_text[i], ha1_text[i + 1], '\0' };
639 		ha1[j] = (unsigned char)strtol(buf, NULL, 0);
640 	}
641 	/* SHA1 output length is 20 bytes, get them all */
642 	bctbx_hmacSha1(ha1, sizeof(ha1), (const unsigned char *)buf, bufsize, 20, (unsigned char *)hmac);
643 	return hmac;
644 }
645 
ms_stun_calculate_integrity_long_term(const char * buf,size_t bufsize,const char * realm,const char * username,const char * password)646 char * ms_stun_calculate_integrity_long_term(const char *buf, size_t bufsize, const char *realm, const char *username, const char *password) {
647 	unsigned char ha1[16];
648 	char ha1_text[1024];
649 	char *hmac = ms_malloc(21);
650 	memset(hmac, 0, 21);
651 	snprintf(ha1_text, sizeof(ha1_text), "%s:%s:%s", username, realm, password);
652 	bctbx_md5((unsigned char *)ha1_text, strlen(ha1_text), ha1);
653 	/* SHA1 output length is 20 bytes, get them all */
654 	bctbx_hmacSha1(ha1, sizeof(ha1), (const unsigned char *)buf, bufsize, 20, (unsigned char *)hmac);
655 	return hmac;
656 }
657 
ms_stun_calculate_fingerprint(const char * buf,size_t bufsize)658 uint32_t ms_stun_calculate_fingerprint(const char *buf, size_t bufsize) {
659 	/*
660 	 *  COPYRIGHT (C) 1986 Gary S. Brown.  You may use this program, or
661 	 *  code or tables extracted from it, as desired without restriction.
662 	 */
663 	static uint32_t crc32_tab[] = {
664 		0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
665 		0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
666 		0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
667 		0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
668 		0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
669 		0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
670 		0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
671 		0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
672 		0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
673 		0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
674 		0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
675 		0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
676 		0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
677 		0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
678 		0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
679 		0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
680 		0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
681 		0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
682 		0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
683 		0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
684 		0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
685 		0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
686 		0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
687 		0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
688 		0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
689 		0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
690 		0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
691 		0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
692 		0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
693 		0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
694 		0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
695 		0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
696 		0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
697 		0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
698 		0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
699 		0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
700 		0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
701 		0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
702 		0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
703 		0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
704 		0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
705 		0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
706 		0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
707 	};
708 	const uint8_t *p = (uint8_t*)buf;
709 	uint32_t crc;
710 
711 	crc = ~0U;
712 	while (bufsize--)
713 		crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
714 	return crc ^ ~0U;
715 }
716 
717 
ms_stun_message_create(uint16_t type,uint16_t method)718 MSStunMessage * ms_stun_message_create(uint16_t type, uint16_t method) {
719 	MSStunMessage *msg = ms_new0(MSStunMessage, 1);
720 	msg->type = type;
721 	msg->method = method;
722 	ms_stun_message_set_random_tr_id(msg);
723 	return msg;
724 }
725 
ms_stun_message_create_from_buffer_parsing(const uint8_t * buf,ssize_t bufsize)726 MSStunMessage * ms_stun_message_create_from_buffer_parsing(const uint8_t *buf, ssize_t bufsize) {
727 	StunMessageDecoder decoder;
728 	MSStunMessage *msg = NULL;
729 
730 	if (bufsize < STUN_MESSAGE_HEADER_LENGTH) {
731 		ms_warning("STUN message too short!");
732 		goto error;
733 	}
734 
735 	msg = ms_new0(MSStunMessage, 1);
736 	stun_message_decoder_init(&decoder, buf, bufsize);
737 	decode_message_header(&decoder, msg);
738 	if (decoder.error) goto error;
739 	if ((ms_stun_message_get_length(msg) + STUN_MESSAGE_HEADER_LENGTH) != bufsize) {
740 		ms_warning("STUN message header length does not match message size: %i - %zd",
741 			ms_stun_message_get_length(msg), bufsize);
742 		goto error;
743 	}
744 
745 	while (decoder.remaining > 0) {
746 		size_t padding;
747 		uint16_t type;
748 		uint16_t length;
749 
750 		decode_attribute_header(&decoder, &type, &length);
751 		if (length > decoder.remaining) {
752 			ms_error("STUN attribute larger than message (attribute type: 0x%4x)", type);
753 			decoder.error = TRUE;
754 		}
755 		if (decoder.error) goto error;
756 		switch (type) {
757 			case MS_STUN_ATTR_MAPPED_ADDRESS:
758 				ms_stun_message_set_mapped_address(msg, decode_addr(&decoder, length));
759 				break;
760 			case MS_STUN_ATTR_CHANGE_REQUEST:
761 				msg->change_request = decode_change_request(&decoder, length);
762 				break;
763 			case MS_STUN_ATTR_RESPONSE_ADDRESS:
764 			case MS_STUN_ATTR_SOURCE_ADDRESS:
765 			case MS_STUN_ATTR_CHANGED_ADDRESS:
766 				/* Ignore these deprecated attributes. */
767 				decode_addr(&decoder, length);
768 				break;
769 			case MS_STUN_ATTR_USERNAME:
770 				{
771 					char *username = decode_string(&decoder, length, STUN_MAX_USERNAME_LENGTH);
772 					ms_stun_message_set_username(msg, username);
773 					if (username != NULL) ms_free(username);
774 				}
775 				break;
776 			case MS_STUN_ATTR_PASSWORD:
777 				/* Ignore this deprecated attribute. */
778 				{
779 					char *password = decode_string(&decoder, length, STUN_MAX_USERNAME_LENGTH);
780 					if (password != NULL) ms_free(password);
781 				}
782 				break;
783 			case MS_STUN_ATTR_MESSAGE_INTEGRITY:
784 				msg->message_integrity = decode_message_integrity(&decoder, length);
785 				msg->has_message_integrity = TRUE;
786 				if (strcmp(ms_stun_message_get_message_integrity(msg), "hmac-not-implemented") == 0) msg->has_dummy_message_integrity = TRUE;
787 				break;
788 			case MS_STUN_ATTR_ERROR_CODE:
789 				{
790 					char *reason = NULL;
791 					uint16_t number = decode_error_code(&decoder, length, &reason);
792 					ms_stun_message_set_error_code(msg, number, reason);
793 					if (reason != NULL) ms_free(reason);
794 				}
795 				break;
796 			case MS_STUN_ATTR_XOR_MAPPED_ADDRESS:
797 				{
798 					MSStunAddress stun_addr = decode_xor_addr(&decoder, length, ms_stun_message_get_tr_id(msg));
799 					ms_stun_message_set_xor_mapped_address(msg, stun_addr);
800 				}
801 				break;
802 			case MS_STUN_ATTR_SOFTWARE:
803 				{
804 					char *software = decode_string(&decoder, length, STUN_MAX_SOFTWARE_LENGTH);
805 					ms_stun_message_set_software(msg, software);
806 					if (software != NULL) ms_free(software);
807 				}
808 				break;
809 			case MS_STUN_ATTR_FINGERPRINT:
810 				msg->fingerprint = decode_fingerprint(&decoder, length);
811 				msg->has_fingerprint = TRUE;
812 				break;
813 			case MS_ICE_ATTR_PRIORITY:
814 				ms_stun_message_set_priority(msg, decode_priority(&decoder, length));
815 				break;
816 			case MS_ICE_ATTR_USE_CANDIDATE:
817 				ms_stun_message_enable_use_candidate(msg, TRUE);
818 				break;
819 			case MS_ICE_ATTR_ICE_CONTROLLED:
820 				ms_stun_message_set_ice_controlled(msg, decode_ice_control(&decoder, length));
821 				break;
822 			case MS_ICE_ATTR_ICE_CONTROLLING:
823 				ms_stun_message_set_ice_controlling(msg, decode_ice_control(&decoder, length));
824 				break;
825 			case MS_TURN_ATTR_XOR_PEER_ADDRESS:
826 				{
827 					MSStunAddress stun_addr = decode_xor_addr(&decoder, length, ms_stun_message_get_tr_id(msg));
828 					ms_stun_message_set_xor_peer_address(msg, stun_addr);
829 				}
830 				break;
831 			case MS_TURN_ATTR_XOR_RELAYED_ADDRESS:
832 				{
833 					MSStunAddress stun_addr = decode_xor_addr(&decoder, length, ms_stun_message_get_tr_id(msg));
834 					ms_stun_message_set_xor_relayed_address(msg, stun_addr);
835 				}
836 				break;
837 			case MS_TURN_ATTR_LIFETIME:
838 				ms_stun_message_set_lifetime(msg, decode_lifetime(&decoder, length));
839 				break;
840 			case MS_TURN_ATTR_DATA:
841 				ms_stun_message_set_data(msg, decode_data(&decoder, length), length);
842 				break;
843 			case MS_STUN_ATTR_REALM:
844 				{
845 					char *realm = decode_string(&decoder, length, STUN_MAX_REALM_LENGTH);
846 					ms_stun_message_set_realm(msg, realm);
847 					if (realm != NULL) ms_free(realm);
848 				}
849 				break;
850 			case MS_STUN_ATTR_NONCE:
851 				{
852 					char *nonce = decode_string(&decoder, length, STUN_MAX_NONCE_LENGTH);
853 					ms_stun_message_set_nonce(msg, nonce);
854 					if (nonce != NULL) ms_free(nonce);
855 				}
856 				break;
857 			default:
858 				if (type <= 0x7FFF) {
859 					ms_error("STUN unknown Comprehension-Required attribute: 0x%04x", type);
860 					goto error;
861 				} else {
862 					ms_warning("STUN unknown attribute: 0x%04x", type);
863 					decode(&decoder, length);
864 				}
865 				break;
866 		}
867 		if (decoder.error) goto error;
868 		padding = 4 - (length % 4);
869 		if (padding < 4) {
870 			size_t i;
871 			for (i = 0; i < padding; i++) decode8(&decoder);
872 			if (decoder.error) goto error;
873 		}
874 	}
875 
876 	return msg;
877 
878 error:
879 	if (msg != NULL) {
880 		ms_free(msg);
881 	}
882 	return NULL;
883 }
884 
ms_stun_binding_request_create(void)885 MSStunMessage * ms_stun_binding_request_create(void) {
886 	return ms_stun_message_create(MS_STUN_TYPE_REQUEST, MS_STUN_METHOD_BINDING);
887 }
888 
ms_stun_binding_success_response_create(void)889 MSStunMessage * ms_stun_binding_success_response_create(void) {
890 	return ms_stun_message_create(MS_STUN_TYPE_SUCCESS_RESPONSE, MS_STUN_METHOD_BINDING);
891 }
892 
ms_stun_binding_error_response_create(void)893 MSStunMessage * ms_stun_binding_error_response_create(void) {
894 	return ms_stun_message_create(MS_STUN_TYPE_ERROR_RESPONSE, MS_STUN_METHOD_BINDING);
895 }
896 
ms_stun_binding_indication_create(void)897 MSStunMessage * ms_stun_binding_indication_create(void) {
898 	return ms_stun_message_create(MS_STUN_TYPE_INDICATION, MS_STUN_METHOD_BINDING);
899 }
900 
ms_stun_message_is_request(const MSStunMessage * msg)901 bool_t ms_stun_message_is_request(const MSStunMessage *msg) {
902 	return (((msg->type) & 0x0110) == MS_STUN_TYPE_REQUEST) ? TRUE : FALSE;
903 }
904 
ms_stun_message_is_success_response(const MSStunMessage * msg)905 bool_t ms_stun_message_is_success_response(const MSStunMessage *msg) {
906 	return (((msg->type) & 0x0110) == MS_STUN_TYPE_SUCCESS_RESPONSE) ? TRUE : FALSE;
907 }
908 
ms_stun_message_is_error_response(const MSStunMessage * msg)909 bool_t ms_stun_message_is_error_response(const MSStunMessage *msg) {
910 	return (((msg->type) & 0x0110) == MS_STUN_TYPE_ERROR_RESPONSE) ? TRUE : FALSE;
911 }
912 
ms_stun_message_is_indication(const MSStunMessage * msg)913 bool_t ms_stun_message_is_indication(const MSStunMessage *msg) {
914 	return (((msg->type) & 0x0110) == MS_STUN_TYPE_INDICATION) ? TRUE : FALSE;
915 }
916 
ms_stun_message_destroy(MSStunMessage * msg)917 void ms_stun_message_destroy(MSStunMessage *msg) {
918 	if (msg->username) ms_free(msg->username);
919 	if (msg->password) {
920 		memset(msg->password, '\0', strlen(msg->password));
921 		ms_free(msg->password);
922 	}
923 	if (msg->ha1) ms_free(msg->ha1);
924 	if (msg->realm) ms_free(msg->realm);
925 	if (msg->nonce) ms_free(msg->nonce);
926 	if (msg->message_integrity) ms_free(msg->message_integrity);
927 	if (msg->software) ms_free(msg->software);
928 	if (msg->error_code.reason) ms_free(msg->error_code.reason);
929 	if (msg->data) ms_free(msg->data);
930 	ms_free(msg);
931 }
932 
ms_stun_message_encode(const MSStunMessage * msg,char ** buf)933 size_t ms_stun_message_encode(const MSStunMessage *msg, char **buf) {
934 	StunMessageEncoder encoder;
935 	const MSStunAddress *stun_addr;
936 	size_t message_length;
937 
938 	stun_message_encoder_init(&encoder);
939 	encode_message_header(&encoder, msg->type, msg->method, &msg->tr_id);
940 
941 	stun_addr = ms_stun_message_get_mapped_address(msg);
942 	if (stun_addr != NULL) encode_addr(&encoder, MS_STUN_ATTR_MAPPED_ADDRESS, stun_addr);
943 	if (msg->change_request != 0) encode_change_request(&encoder, msg->change_request);
944 	if (msg->username != NULL) encode_string(&encoder, MS_STUN_ATTR_USERNAME, msg->username, STUN_MAX_USERNAME_LENGTH);
945 	if (msg->realm != NULL) encode_string(&encoder, MS_STUN_ATTR_REALM, msg->realm, STUN_MAX_REALM_LENGTH);
946 	if (msg->nonce != NULL) encode_string(&encoder, MS_STUN_ATTR_NONCE, msg->nonce, STUN_MAX_NONCE_LENGTH);
947 	if (ms_stun_message_has_error_code(msg)) {
948 		char *reason = NULL;
949 		uint16_t number = ms_stun_message_get_error_code(msg, &reason);
950 		encode_error_code(&encoder, number, reason);
951 	}
952 	stun_addr = ms_stun_message_get_xor_mapped_address(msg);
953 	if (stun_addr != NULL) encode_xor_addr(&encoder, MS_STUN_ATTR_XOR_MAPPED_ADDRESS, stun_addr, &msg->tr_id);
954 
955 	stun_addr = ms_stun_message_get_xor_peer_address(msg);
956 	if (stun_addr != NULL) encode_xor_addr(&encoder, MS_TURN_ATTR_XOR_PEER_ADDRESS, stun_addr, &msg->tr_id);
957 	stun_addr = ms_stun_message_get_xor_relayed_address(msg);
958 	if (stun_addr != NULL) encode_xor_addr(&encoder, MS_TURN_ATTR_XOR_RELAYED_ADDRESS, stun_addr, &msg->tr_id);
959 	if (ms_stun_message_has_requested_transport(msg)) encode_requested_transport(&encoder, ms_stun_message_get_requested_transport(msg));
960 	if (ms_stun_message_has_requested_address_family(msg)) encode_requested_address_family(&encoder, ms_stun_message_get_requested_address_family(msg));
961 	if (ms_stun_message_has_lifetime(msg)) encode_lifetime(&encoder, ms_stun_message_get_lifetime(msg));
962 	if (ms_stun_message_has_channel_number(msg)) encode_channel_number(&encoder, ms_stun_message_get_channel_number(msg));
963 	if ((ms_stun_message_get_data(msg) != NULL) && (ms_stun_message_get_data_length(msg) > 0))
964 		encode_data(&encoder, ms_stun_message_get_data(msg), ms_stun_message_get_data_length(msg));
965 
966 	if (ms_stun_message_has_priority(msg)) encode_priority(&encoder, ms_stun_message_get_priority(msg));
967 	if (ms_stun_message_use_candidate_enabled(msg)) encode_use_candidate(&encoder);
968 	if (ms_stun_message_has_ice_controlled(msg))
969 		encode_ice_control(&encoder, MS_ICE_ATTR_ICE_CONTROLLED, ms_stun_message_get_ice_controlled(msg));
970 	if (ms_stun_message_has_ice_controlling(msg))
971 		encode_ice_control(&encoder, MS_ICE_ATTR_ICE_CONTROLLING, ms_stun_message_get_ice_controlling(msg));
972 	if (ms_stun_message_message_integrity_enabled(msg)) {
973 		const char *username = ms_stun_message_get_username(msg);
974 		const char *password = ms_stun_message_get_password(msg);
975 		if (msg->ha1 != NULL) {
976 			encode_long_term_integrity_from_ha1(&encoder, msg->ha1);
977 		} else if ((username != NULL) && (password != NULL) && (strlen(username) > 0) && (strlen(password) > 0)) {
978 			const char *realm = ms_stun_message_get_realm(msg);
979 			if ((realm != NULL) && (strlen(realm) > 0)) {
980 				encode_long_term_integrity(&encoder, realm, username, password);
981 			} else {
982 				encode_short_term_integrity(&encoder, password, ms_stun_message_dummy_message_integrity_enabled(msg));
983 			}
984 		}
985 	}
986 	if (ms_stun_message_fingerprint_enabled(msg)) encode_fingerprint(&encoder);
987 
988 	message_length = stun_message_encoder_get_message_length(&encoder);
989 	encode_message_length(&encoder, message_length - STUN_MESSAGE_HEADER_LENGTH);
990 	*buf = encoder.buffer;
991 	return message_length;
992 }
993 
ms_stun_message_get_method(const MSStunMessage * msg)994 uint16_t ms_stun_message_get_method(const MSStunMessage *msg) {
995 	return msg->method;
996 }
997 
ms_stun_message_get_length(const MSStunMessage * msg)998 uint16_t ms_stun_message_get_length(const MSStunMessage *msg) {
999 	return msg->length;
1000 }
1001 
ms_stun_message_get_tr_id(const MSStunMessage * msg)1002 UInt96 ms_stun_message_get_tr_id(const MSStunMessage *msg) {
1003 	return  msg->tr_id;
1004 }
1005 
ms_stun_message_set_tr_id(MSStunMessage * msg,UInt96 tr_id)1006 void ms_stun_message_set_tr_id(MSStunMessage *msg, UInt96 tr_id) {
1007 	msg->tr_id = tr_id;
1008 }
1009 
ms_stun_message_set_random_tr_id(MSStunMessage * msg)1010 void ms_stun_message_set_random_tr_id(MSStunMessage *msg) {
1011 	UInt96 tr_id;
1012 	int i;
1013 
1014 	for (i = 0; i < 12; i += 4) {
1015 		unsigned int r = ortp_random();
1016 		tr_id.octet[i + 0] = r >> 0;
1017 		tr_id.octet[i + 1] = r >> 8;
1018 		tr_id.octet[i + 2] = r >> 16;
1019 		tr_id.octet[i + 3] = r >> 24;
1020 	}
1021 	ms_stun_message_set_tr_id(msg, tr_id);
1022 }
1023 
ms_stun_message_get_username(const MSStunMessage * msg)1024 const char * ms_stun_message_get_username(const MSStunMessage *msg) {
1025 	return msg->username;
1026 }
1027 
ms_stun_message_set_username(MSStunMessage * msg,const char * username)1028 void ms_stun_message_set_username(MSStunMessage *msg, const char *username) {
1029 	STUN_STR_SETTER(msg->username, username);
1030 	msg->include_username_attribute = TRUE;
1031 }
1032 
ms_stun_message_include_username_attribute(MSStunMessage * msg,bool_t include)1033 void ms_stun_message_include_username_attribute(MSStunMessage *msg, bool_t include) {
1034 	msg->include_username_attribute = include;
1035 }
1036 
ms_stun_message_get_password(const MSStunMessage * msg)1037 const char * ms_stun_message_get_password(const MSStunMessage *msg) {
1038 	return msg->password;
1039 }
1040 
ms_stun_message_set_password(MSStunMessage * msg,const char * password)1041 void ms_stun_message_set_password(MSStunMessage *msg, const char *password) {
1042 	STUN_STR_SETTER(msg->password, password);
1043 }
1044 
ms_stun_message_set_ha1(MSStunMessage * msg,const char * ha1)1045 void ms_stun_message_set_ha1(MSStunMessage *msg, const char *ha1) {
1046 	STUN_STR_SETTER(msg->ha1, ha1);
1047 }
1048 
ms_stun_message_get_realm(const MSStunMessage * msg)1049 const char * ms_stun_message_get_realm(const MSStunMessage *msg) {
1050 	return msg->realm;
1051 }
1052 
ms_stun_message_set_realm(MSStunMessage * msg,const char * realm)1053 void ms_stun_message_set_realm(MSStunMessage *msg, const char *realm) {
1054 	STUN_STR_SETTER(msg->realm, realm);
1055 }
1056 
ms_stun_message_get_software(const MSStunMessage * msg)1057 const char * ms_stun_message_get_software(const MSStunMessage *msg) {
1058 	return msg->software;
1059 }
1060 
ms_stun_message_set_software(MSStunMessage * msg,const char * software)1061 void ms_stun_message_set_software(MSStunMessage *msg, const char *software) {
1062 	STUN_STR_SETTER(msg->software, software);
1063 }
1064 
ms_stun_message_get_nonce(const MSStunMessage * msg)1065 const char * ms_stun_message_get_nonce(const MSStunMessage *msg) {
1066 	return msg->nonce;
1067 }
1068 
ms_stun_message_set_nonce(MSStunMessage * msg,const char * nonce)1069 void ms_stun_message_set_nonce(MSStunMessage *msg, const char *nonce) {
1070 	STUN_STR_SETTER(msg->nonce, nonce);
1071 }
1072 
ms_stun_message_has_error_code(const MSStunMessage * msg)1073 bool_t ms_stun_message_has_error_code(const MSStunMessage *msg) {
1074 	return msg->has_error_code;
1075 }
1076 
ms_stun_message_get_error_code(const MSStunMessage * msg,char ** reason)1077 uint16_t ms_stun_message_get_error_code(const MSStunMessage *msg, char **reason) {
1078 	if (reason != NULL) {
1079 		*reason = msg->error_code.reason;
1080 	}
1081 	return msg->error_code.number;
1082 }
1083 
ms_stun_message_set_error_code(MSStunMessage * msg,uint16_t number,const char * reason)1084 void ms_stun_message_set_error_code(MSStunMessage *msg, uint16_t number, const char *reason) {
1085 	msg->error_code.number = number;
1086 	STUN_STR_SETTER(msg->error_code.reason, reason);
1087 	msg->has_error_code = TRUE;
1088 }
1089 
ms_stun_message_message_integrity_enabled(const MSStunMessage * msg)1090 bool_t ms_stun_message_message_integrity_enabled(const MSStunMessage *msg) {
1091 	return msg->has_message_integrity;
1092 }
1093 
ms_stun_message_enable_message_integrity(MSStunMessage * msg,bool_t enable)1094 void ms_stun_message_enable_message_integrity(MSStunMessage *msg, bool_t enable) {
1095 	msg->has_message_integrity = enable;
1096 }
1097 
ms_stun_message_get_message_integrity(const MSStunMessage * msg)1098 const char * ms_stun_message_get_message_integrity(const MSStunMessage *msg) {
1099 	return msg->message_integrity;
1100 }
1101 
ms_stun_message_fingerprint_enabled(const MSStunMessage * msg)1102 bool_t ms_stun_message_fingerprint_enabled(const MSStunMessage *msg) {
1103 	return msg->has_fingerprint;
1104 }
1105 
ms_stun_message_enable_fingerprint(MSStunMessage * msg,bool_t enable)1106 void ms_stun_message_enable_fingerprint(MSStunMessage *msg, bool_t enable) {
1107 	msg->has_fingerprint = enable;
1108 }
1109 
ms_stun_message_get_mapped_address(const MSStunMessage * msg)1110 const MSStunAddress * ms_stun_message_get_mapped_address(const MSStunMessage *msg) {
1111 	if (msg->has_mapped_address) return &msg->mapped_address;
1112 	return NULL;
1113 }
1114 
ms_stun_message_set_mapped_address(MSStunMessage * msg,MSStunAddress mapped_address)1115 void ms_stun_message_set_mapped_address(MSStunMessage *msg, MSStunAddress mapped_address) {
1116 	msg->mapped_address = mapped_address;
1117 	msg->has_mapped_address = TRUE;
1118 }
1119 
ms_stun_message_get_xor_mapped_address(const MSStunMessage * msg)1120 const MSStunAddress * ms_stun_message_get_xor_mapped_address(const MSStunMessage *msg) {
1121 	if (msg->has_xor_mapped_address) return &msg->xor_mapped_address;
1122 	return NULL;
1123 }
1124 
ms_stun_message_set_xor_mapped_address(MSStunMessage * msg,MSStunAddress xor_mapped_address)1125 void ms_stun_message_set_xor_mapped_address(MSStunMessage *msg, MSStunAddress xor_mapped_address) {
1126 	msg->xor_mapped_address = xor_mapped_address;
1127 	msg->has_xor_mapped_address = TRUE;
1128 }
1129 
ms_stun_message_get_xor_peer_address(const MSStunMessage * msg)1130 const MSStunAddress * ms_stun_message_get_xor_peer_address(const MSStunMessage *msg) {
1131 	if (msg->has_xor_peer_address) return &msg->xor_peer_address;
1132 	return NULL;
1133 }
1134 
ms_stun_message_set_xor_peer_address(MSStunMessage * msg,MSStunAddress xor_peer_address)1135 void ms_stun_message_set_xor_peer_address(MSStunMessage *msg, MSStunAddress xor_peer_address) {
1136 	msg->xor_peer_address = xor_peer_address;
1137 	msg->has_xor_peer_address = TRUE;
1138 }
1139 
ms_stun_message_get_xor_relayed_address(const MSStunMessage * msg)1140 const MSStunAddress * ms_stun_message_get_xor_relayed_address(const MSStunMessage *msg) {
1141 	if (msg->has_xor_relayed_address) return &msg->xor_relayed_address;
1142 	return NULL;
1143 }
1144 
ms_stun_message_set_xor_relayed_address(MSStunMessage * msg,MSStunAddress xor_relayed_address)1145 void ms_stun_message_set_xor_relayed_address(MSStunMessage *msg, MSStunAddress xor_relayed_address) {
1146 	msg->xor_relayed_address = xor_relayed_address;
1147 	msg->has_xor_relayed_address = TRUE;
1148 }
1149 
ms_stun_message_enable_change_ip(MSStunMessage * msg,bool_t enable)1150 void ms_stun_message_enable_change_ip(MSStunMessage *msg, bool_t enable) {
1151 	if (enable) msg->change_request |= STUN_FLAG_CHANGE_IP;
1152 	else {
1153 		uint32_t mask = STUN_FLAG_CHANGE_IP;
1154 		msg->change_request &= ~mask;
1155 	}
1156 }
1157 
ms_stun_message_enable_change_port(MSStunMessage * msg,bool_t enable)1158 void ms_stun_message_enable_change_port(MSStunMessage *msg, bool_t enable) {
1159 	if (enable) msg->change_request |= STUN_FLAG_CHANGE_PORT;
1160 	else {
1161 		uint32_t mask = STUN_FLAG_CHANGE_PORT;
1162 		msg->change_request &= ~mask;
1163 	}
1164 }
1165 
ms_stun_message_has_priority(const MSStunMessage * msg)1166 bool_t ms_stun_message_has_priority(const MSStunMessage *msg) {
1167 	return msg->has_priority;
1168 }
1169 
ms_stun_message_get_priority(const MSStunMessage * msg)1170 uint32_t ms_stun_message_get_priority(const MSStunMessage *msg) {
1171 	return msg->priority;
1172 }
1173 
ms_stun_message_set_priority(MSStunMessage * msg,uint32_t priority)1174 void ms_stun_message_set_priority(MSStunMessage *msg, uint32_t priority) {
1175 	msg->priority = priority;
1176 	msg->has_priority = TRUE;
1177 }
1178 
ms_stun_message_use_candidate_enabled(const MSStunMessage * msg)1179 bool_t ms_stun_message_use_candidate_enabled(const MSStunMessage *msg) {
1180 	return msg->has_use_candidate;
1181 }
1182 
ms_stun_message_enable_use_candidate(MSStunMessage * msg,bool_t enable)1183 void ms_stun_message_enable_use_candidate(MSStunMessage *msg, bool_t enable) {
1184 	msg->has_use_candidate = enable;
1185 }
1186 
ms_stun_message_has_ice_controlling(const MSStunMessage * msg)1187 bool_t ms_stun_message_has_ice_controlling(const MSStunMessage *msg) {
1188 	return msg->has_ice_controlling;
1189 }
1190 
ms_stun_message_get_ice_controlling(const MSStunMessage * msg)1191 uint64_t ms_stun_message_get_ice_controlling(const MSStunMessage *msg) {
1192 	return msg->ice_controlling;
1193 }
1194 
ms_stun_message_set_ice_controlling(MSStunMessage * msg,uint64_t value)1195 void ms_stun_message_set_ice_controlling(MSStunMessage *msg, uint64_t value) {
1196 	msg->ice_controlling = value;
1197 	msg->has_ice_controlling = TRUE;
1198 }
1199 
ms_stun_message_has_ice_controlled(const MSStunMessage * msg)1200 bool_t ms_stun_message_has_ice_controlled(const MSStunMessage *msg) {
1201 	return msg->has_ice_controlled;
1202 }
1203 
ms_stun_message_get_ice_controlled(const MSStunMessage * msg)1204 uint64_t ms_stun_message_get_ice_controlled(const MSStunMessage *msg) {
1205 	return msg->ice_controlled;
1206 }
1207 
ms_stun_message_set_ice_controlled(MSStunMessage * msg,uint64_t value)1208 void ms_stun_message_set_ice_controlled(MSStunMessage *msg, uint64_t value) {
1209 	msg->ice_controlled = value;
1210 	msg->has_ice_controlled = TRUE;
1211 }
1212 
ms_stun_message_dummy_message_integrity_enabled(const MSStunMessage * msg)1213 bool_t ms_stun_message_dummy_message_integrity_enabled(const MSStunMessage *msg) {
1214 	return msg->has_dummy_message_integrity;
1215 }
1216 
ms_stun_message_enable_dummy_message_integrity(MSStunMessage * msg,bool_t enable)1217 void ms_stun_message_enable_dummy_message_integrity(MSStunMessage *msg, bool_t enable) {
1218 	msg->has_dummy_message_integrity = enable;
1219 }
1220 
ms_turn_allocate_request_create(void)1221 MSStunMessage * ms_turn_allocate_request_create(void) {
1222 	MSStunMessage *msg = ms_stun_message_create(MS_STUN_TYPE_REQUEST, MS_TURN_METHOD_ALLOCATE);
1223 	msg->requested_transport = IANA_PROTOCOL_NUMBERS_UDP;
1224 	msg->has_requested_transport = TRUE;
1225 	return msg;
1226 }
1227 
ms_turn_refresh_request_create(uint32_t lifetime)1228 MSStunMessage * ms_turn_refresh_request_create(uint32_t lifetime) {
1229 	MSStunMessage *msg = ms_stun_message_create(MS_STUN_TYPE_REQUEST, MS_TURN_METHOD_REFRESH);
1230 	ms_stun_message_set_lifetime(msg, lifetime);
1231 	return msg;
1232 }
1233 
ms_turn_create_permission_request_create(MSStunAddress peer_address)1234 MSStunMessage * ms_turn_create_permission_request_create(MSStunAddress peer_address) {
1235 	MSStunMessage *msg = ms_stun_message_create(MS_STUN_TYPE_REQUEST, MS_TURN_METHOD_CREATE_PERMISSION);
1236 	ms_stun_message_set_xor_peer_address(msg, peer_address);
1237 	return msg;
1238 }
1239 
ms_turn_send_indication_create(MSStunAddress peer_address)1240 MSStunMessage * ms_turn_send_indication_create(MSStunAddress peer_address) {
1241 	MSStunMessage *msg = ms_stun_message_create(MS_STUN_TYPE_INDICATION, MS_TURN_METHOD_SEND);
1242 	ms_stun_message_set_xor_peer_address(msg, peer_address);
1243 	return msg;
1244 }
1245 
ms_turn_channel_bind_request_create(MSStunAddress peer_address,uint16_t channel_number)1246 MSStunMessage * ms_turn_channel_bind_request_create(MSStunAddress peer_address, uint16_t channel_number) {
1247 	MSStunMessage *msg = ms_stun_message_create(MS_STUN_TYPE_REQUEST, MS_TURN_METHOD_CHANNEL_BIND);
1248 	ms_stun_message_set_xor_peer_address(msg, peer_address);
1249 	ms_stun_message_set_channel_number(msg, channel_number);
1250 	return msg;
1251 }
1252 
ms_stun_message_has_requested_transport(const MSStunMessage * msg)1253 bool_t ms_stun_message_has_requested_transport(const MSStunMessage *msg) {
1254 	return msg->has_requested_transport;
1255 }
1256 
ms_stun_message_get_requested_transport(const MSStunMessage * msg)1257 uint8_t ms_stun_message_get_requested_transport(const MSStunMessage *msg) {
1258 	return msg->requested_transport;
1259 }
1260 
ms_stun_message_has_requested_address_family(const MSStunMessage * msg)1261 bool_t ms_stun_message_has_requested_address_family(const MSStunMessage *msg) {
1262 	return msg->has_requested_address_family;
1263 }
1264 
ms_stun_message_get_requested_address_family(const MSStunMessage * msg)1265 uint8_t ms_stun_message_get_requested_address_family(const MSStunMessage *msg) {
1266 	return msg->requested_address_family;
1267 }
1268 
ms_stun_message_set_requested_address_family(MSStunMessage * msg,uint8_t family)1269 void ms_stun_message_set_requested_address_family(MSStunMessage *msg, uint8_t family) {
1270 	msg->requested_address_family = family;
1271 	msg->has_requested_address_family = TRUE;
1272 }
1273 
ms_stun_message_has_lifetime(const MSStunMessage * msg)1274 bool_t ms_stun_message_has_lifetime(const MSStunMessage *msg) {
1275 	return msg->has_lifetime;
1276 }
1277 
ms_stun_message_get_lifetime(const MSStunMessage * msg)1278 uint32_t ms_stun_message_get_lifetime(const MSStunMessage *msg) {
1279 	return msg->lifetime;
1280 }
1281 
ms_stun_message_set_lifetime(MSStunMessage * msg,uint32_t lifetime)1282 void ms_stun_message_set_lifetime(MSStunMessage *msg, uint32_t lifetime) {
1283 	msg->lifetime = lifetime;
1284 	msg->has_lifetime = TRUE;
1285 }
1286 
ms_stun_message_has_channel_number(const MSStunMessage * msg)1287 bool_t ms_stun_message_has_channel_number(const MSStunMessage *msg) {
1288 	return msg->has_channel_number;
1289 }
1290 
ms_stun_message_get_channel_number(const MSStunMessage * msg)1291 uint16_t ms_stun_message_get_channel_number(const MSStunMessage *msg) {
1292 	return msg->channel_number;
1293 }
1294 
ms_stun_message_set_channel_number(MSStunMessage * msg,uint16_t channel_number)1295 void ms_stun_message_set_channel_number(MSStunMessage *msg, uint16_t channel_number) {
1296 	msg->channel_number = channel_number;
1297 	msg->has_channel_number = TRUE;
1298 }
1299 
ms_stun_message_get_data(const MSStunMessage * msg)1300 uint8_t * ms_stun_message_get_data(const MSStunMessage *msg) {
1301 	return msg->data;
1302 }
1303 
ms_stun_message_get_data_length(const MSStunMessage * msg)1304 uint16_t ms_stun_message_get_data_length(const MSStunMessage *msg) {
1305 	return msg->data_length;
1306 }
1307 
ms_stun_message_set_data(MSStunMessage * msg,uint8_t * data,uint16_t length)1308 void ms_stun_message_set_data(MSStunMessage *msg, uint8_t *data, uint16_t length) {
1309 	if (msg->data != NULL) {
1310 		ms_free(msg->data);
1311 		msg->data = NULL;
1312 	}
1313 	msg->data = data;
1314 	msg->data_length = length;
1315 }
1316 
1317 
ms_turn_context_new(MSTurnContextType type,RtpSession * rtp_session)1318 MSTurnContext * ms_turn_context_new(MSTurnContextType type, RtpSession *rtp_session) {
1319 	MSTurnContext *context = ms_new0(MSTurnContext, 1);
1320 	context->state = MS_TURN_CONTEXT_STATE_IDLE;
1321 	context->type = type;
1322 	context->rtp_session = rtp_session;
1323 	return context;
1324 }
1325 
ms_turn_context_destroy(MSTurnContext * context)1326 void ms_turn_context_destroy(MSTurnContext *context) {
1327 	if (context->realm != NULL) ms_free(context->realm);
1328 	if (context->nonce != NULL) ms_free(context->nonce);
1329 	if (context->username != NULL) ms_free(context->username);
1330 	if (context->password != NULL) {
1331 		memset(context->password, '\0', strlen(context->password));
1332 		ms_free(context->password);
1333 	}
1334 	if (context->ha1 != NULL) ms_free(context->ha1);
1335 	if (context->endpoint != NULL) context->endpoint->data = NULL;
1336 	bctbx_list_for_each(context->allowed_peer_addresses, (MSIterateFunc)ms_free);
1337 	bctbx_list_free(context->allowed_peer_addresses);
1338 	ms_free(context);
1339 }
1340 
ms_turn_context_set_server_addr(MSTurnContext * context,struct sockaddr * addr,socklen_t addrlen)1341 void ms_turn_context_set_server_addr(MSTurnContext *context, struct sockaddr *addr, socklen_t addrlen) {
1342 	context->turn_server_addr = addr;
1343 	context->turn_server_addrlen = addrlen;
1344 }
1345 
ms_turn_context_get_state(const MSTurnContext * context)1346 MSTurnContextState ms_turn_context_get_state(const MSTurnContext *context) {
1347 	return context->state;
1348 }
1349 
ms_turn_context_set_state(MSTurnContext * context,MSTurnContextState state)1350 void ms_turn_context_set_state(MSTurnContext *context, MSTurnContextState state) {
1351 	context->state = state;
1352 	if (state == MS_TURN_CONTEXT_STATE_ALLOCATION_CREATED) context->stats.nb_successful_allocate++;
1353 	else if (state == MS_TURN_CONTEXT_STATE_CHANNEL_BOUND) context->stats.nb_successful_channel_bind++;
1354 }
1355 
ms_turn_context_get_realm(const MSTurnContext * context)1356 const char * ms_turn_context_get_realm(const MSTurnContext *context) {
1357 	return context->realm;
1358 }
1359 
ms_turn_context_set_realm(MSTurnContext * context,const char * realm)1360 void ms_turn_context_set_realm(MSTurnContext *context, const char *realm) {
1361 	STUN_STR_SETTER(context->realm, realm);
1362 }
1363 
ms_turn_context_get_nonce(const MSTurnContext * context)1364 const char * ms_turn_context_get_nonce(const MSTurnContext *context) {
1365 	return context->nonce;
1366 }
1367 
ms_turn_context_set_nonce(MSTurnContext * context,const char * nonce)1368 void ms_turn_context_set_nonce(MSTurnContext *context, const char *nonce) {
1369 	STUN_STR_SETTER(context->nonce, nonce);
1370 }
1371 
ms_turn_context_get_username(const MSTurnContext * context)1372 const char * ms_turn_context_get_username(const MSTurnContext *context) {
1373 	return context->username;
1374 }
1375 
ms_turn_context_set_username(MSTurnContext * context,const char * username)1376 void ms_turn_context_set_username(MSTurnContext *context, const char *username) {
1377 	STUN_STR_SETTER(context->username, username);
1378 }
1379 
ms_turn_context_get_password(const MSTurnContext * context)1380 const char * ms_turn_context_get_password(const MSTurnContext *context) {
1381 	return context->password;
1382 }
1383 
ms_turn_context_set_password(MSTurnContext * context,const char * password)1384 void ms_turn_context_set_password(MSTurnContext *context, const char *password) {
1385 	STUN_STR_SETTER(context->password, password);
1386 }
1387 
ms_turn_context_get_ha1(const MSTurnContext * context)1388 const char * ms_turn_context_get_ha1(const MSTurnContext *context) {
1389 	return context->ha1;
1390 }
1391 
ms_turn_context_set_ha1(MSTurnContext * context,const char * ha1)1392 void ms_turn_context_set_ha1(MSTurnContext *context, const char *ha1) {
1393 	STUN_STR_SETTER(context->ha1, ha1);
1394 }
1395 
ms_turn_context_get_lifetime(const MSTurnContext * context)1396 uint32_t ms_turn_context_get_lifetime(const MSTurnContext *context) {
1397 	return context->lifetime;
1398 }
1399 
ms_turn_context_set_lifetime(MSTurnContext * context,uint32_t lifetime)1400 void ms_turn_context_set_lifetime(MSTurnContext *context, uint32_t lifetime) {
1401 	context->lifetime = lifetime;
1402 }
1403 
ms_turn_context_get_channel_number(const MSTurnContext * context)1404 uint16_t ms_turn_context_get_channel_number(const MSTurnContext *context) {
1405 	return context->channel_number;
1406 }
1407 
ms_turn_context_set_channel_number(MSTurnContext * context,uint16_t channel_number)1408 void ms_turn_context_set_channel_number(MSTurnContext *context, uint16_t channel_number) {
1409 	context->channel_number = channel_number;
1410 }
1411 
ms_turn_context_set_allocated_relay_addr(MSTurnContext * context,MSStunAddress relay_addr)1412 void ms_turn_context_set_allocated_relay_addr(MSTurnContext *context, MSStunAddress relay_addr) {
1413 	context->relay_addr = relay_addr;
1414 }
1415 
ms_turn_context_set_force_rtp_sending_via_relay(MSTurnContext * context,bool_t force)1416 void ms_turn_context_set_force_rtp_sending_via_relay(MSTurnContext *context, bool_t force) {
1417 	context->force_rtp_sending_via_relay = force;
1418 }
1419 
ms_turn_context_peer_address_allowed(const MSTurnContext * context,const MSStunAddress * peer_address)1420 bool_t ms_turn_context_peer_address_allowed(const MSTurnContext *context, const MSStunAddress *peer_address) {
1421 	bctbx_list_t *elem = context->allowed_peer_addresses;
1422 	while (elem != NULL) {
1423 		MSStunAddress *allowed_peer = (MSStunAddress *)elem->data;
1424 		if (ms_compare_stun_addresses(allowed_peer, peer_address) == FALSE) return TRUE;
1425 		elem = elem->next;
1426 	}
1427 	return FALSE;
1428 }
1429 
ms_turn_context_allow_peer_address(MSTurnContext * context,const MSStunAddress * peer_address)1430 void ms_turn_context_allow_peer_address(MSTurnContext *context, const MSStunAddress *peer_address) {
1431 	if (!ms_turn_context_peer_address_allowed(context, peer_address)) {
1432 		MSStunAddress *new_peer = ms_malloc(sizeof(MSStunAddress));
1433 		memcpy(new_peer, peer_address, sizeof(MSStunAddress));
1434 		context->allowed_peer_addresses = bctbx_list_append(context->allowed_peer_addresses, new_peer);
1435 		context->stats.nb_successful_create_permission++;
1436 	}
1437 }
1438 
ms_turn_rtp_endpoint_recvfrom(RtpTransport * rtptp,mblk_t * msg,int flags,struct sockaddr * from,socklen_t * fromlen)1439 static int ms_turn_rtp_endpoint_recvfrom(RtpTransport *rtptp, mblk_t *msg, int flags, struct sockaddr *from, socklen_t *fromlen) {
1440 	MSTurnContext *context = (MSTurnContext *)rtptp->data;
1441 	int msgsize = 0;
1442 
1443 	if ((context != NULL) && (context->rtp_session != NULL)) {
1444 		msgsize = rtp_session_recvfrom(context->rtp_session, context->type == MS_TURN_CONTEXT_TYPE_RTP, msg, flags, from, fromlen);
1445 		if ((msgsize >= RTP_FIXED_HEADER_SIZE) && (rtp_get_version(msg) != 2)) {
1446 			/* This is not a RTP packet, try to see if it is a TURN ChannelData message */
1447 			if ((ms_turn_context_get_state(context) >= MS_TURN_CONTEXT_STATE_BINDING_CHANNEL) && (*msg->b_rptr & 0x40)) {
1448 				uint16_t channel = ntohs(*((uint16_t *)msg->b_rptr));
1449 				uint16_t datasize = ntohs(*(((uint16_t *)msg->b_rptr) + 1));
1450 				if ((channel == ms_turn_context_get_channel_number(context)) && (msgsize >= (datasize + 4))) {
1451 					msg->b_rptr += 4; /* Unpack the TURN ChannelData message */
1452 					context->stats.nb_received_channel_msg++;
1453 				}
1454 			} else {
1455 				/* This is not a RTP packet and not a TURN ChannelData message, try to see if it is a STUN one */
1456 				uint16_t stunlen = ntohs(*((uint16_t*)(msg->b_rptr + sizeof(uint16_t))));
1457 				if (msgsize == (stunlen + 20)) {
1458 					/* It seems to be a STUN packet */
1459 					MSStunMessage *stun_msg = ms_stun_message_create_from_buffer_parsing(msg->b_rptr, msgsize);
1460 					if (stun_msg != NULL) {
1461 						if (ms_stun_message_is_indication(stun_msg)
1462 							&& (ms_stun_message_get_data(stun_msg) != NULL) && (ms_stun_message_get_data_length(stun_msg) > 0)) {
1463 							/* This is TURN data indication */
1464 							const MSStunAddress *stun_addr = ms_stun_message_get_xor_peer_address(stun_msg);
1465 							if (stun_addr != NULL) {
1466 								MSStunAddress permission_addr = *stun_addr;
1467 								ms_stun_address_set_port(&permission_addr, 0);
1468 								if (ms_turn_context_peer_address_allowed(context, &permission_addr) == TRUE) {
1469 									struct sockaddr_storage relay_ss;
1470 									struct sockaddr *relay_sa = (struct sockaddr *)&relay_ss;
1471 									socklen_t relay_sa_len = sizeof(relay_ss);
1472 									memset(relay_sa, 0, relay_sa_len);
1473 									/* Copy the data of the TURN data indication in the mblk_t so that it contains the unpacked data */
1474 									msgsize = ms_stun_message_get_data_length(stun_msg);
1475 									memcpy(msg->b_rptr, ms_stun_message_get_data(stun_msg), msgsize);
1476 									/* Overwrite the ortp_recv_addr of the mblk_t so that ICE source address is correct */
1477 									ms_stun_address_to_sockaddr(&context->relay_addr, relay_sa, &relay_sa_len);
1478 									msg->recv_addr.family = relay_sa->sa_family;
1479 									if (relay_sa->sa_family == AF_INET) {
1480 										msg->recv_addr.addr.ipi_addr = ((struct sockaddr_in *)relay_sa)->sin_addr;
1481 										msg->recv_addr.port = ((struct sockaddr_in *)relay_sa)->sin_port;
1482 									} else if (relay_sa->sa_family == AF_INET6) {
1483 										memcpy(&msg->recv_addr.addr.ipi6_addr, &((struct sockaddr_in6 *)relay_sa)->sin6_addr, sizeof(struct in6_addr));
1484 										msg->recv_addr.port = ((struct sockaddr_in6 *)relay_sa)->sin6_port;
1485 									} else {
1486 										ms_warning("turn: Unknown address family in relay_addr");
1487 										msgsize = 0;
1488 									}
1489 									/* Overwrite the source address of the packet so that it uses the peer address instead of the TURN server one */
1490 									ms_stun_address_to_sockaddr(stun_addr, from, fromlen);
1491 									if (msgsize > 0) context->stats.nb_data_indication++;
1492 								}
1493 							}
1494 						}
1495 						ms_stun_message_destroy(stun_msg);
1496 					}
1497 				}
1498 			}
1499 		}
1500 	}
1501 	return msgsize;
1502 }
1503 
ms_turn_rtp_endpoint_send_via_turn_server(MSTurnContext * context,const struct sockaddr * from,socklen_t fromlen)1504 static bool_t ms_turn_rtp_endpoint_send_via_turn_server(MSTurnContext *context, const struct sockaddr *from, socklen_t fromlen) {
1505 	struct sockaddr_storage relay_ss;
1506 	struct sockaddr *relay_sa = (struct sockaddr *)&relay_ss;
1507 	socklen_t relay_sa_len = sizeof(relay_ss);
1508 
1509 	memset(relay_sa, 0, relay_sa_len);
1510 	ms_stun_address_to_sockaddr(&context->relay_addr, relay_sa, &relay_sa_len);
1511 	if (relay_sa->sa_family != from->sa_family) return FALSE;
1512 	if (relay_sa->sa_family == AF_INET) {
1513 		struct sockaddr_in *relay_sa_in = (struct sockaddr_in *)relay_sa;
1514 		struct sockaddr_in *from_in = (struct sockaddr_in *)from;
1515 		return (relay_sa_in->sin_port == from_in->sin_port) && (relay_sa_in->sin_addr.s_addr == from_in->sin_addr.s_addr);
1516 	} else if (relay_sa->sa_family == AF_INET6) {
1517 		struct sockaddr_in6 *relay_sa_in6 = (struct sockaddr_in6 *)relay_sa;
1518 		struct sockaddr_in6 *from_in6 = (struct sockaddr_in6 *)from;
1519 		return (relay_sa_in6->sin6_port == from_in6->sin6_port) && (memcmp(&relay_sa_in6->sin6_addr, &from_in6->sin6_addr, sizeof(struct in6_addr)) == 0);
1520 	} else return FALSE;
1521 }
1522 
ms_turn_rtp_endpoint_sendto(RtpTransport * rtptp,mblk_t * msg,int flags,const struct sockaddr * to,socklen_t tolen)1523 static int ms_turn_rtp_endpoint_sendto(RtpTransport *rtptp, mblk_t *msg, int flags, const struct sockaddr *to, socklen_t tolen) {
1524 	MSTurnContext *context = (MSTurnContext *)rtptp->data;
1525 	MSStunMessage *stun_msg = NULL;
1526 	bool_t rtp_packet = FALSE;
1527 	int ret = 0;
1528 	mblk_t *new_msg = NULL;
1529 
1530 	if ((context != NULL) && (context->rtp_session != NULL)) {
1531 		if ((msgdsize(msg) >= RTP_FIXED_HEADER_SIZE) && (rtp_get_version(msg) == 2)) rtp_packet = TRUE;
1532 		if ((rtp_packet && context->force_rtp_sending_via_relay) || ms_turn_rtp_endpoint_send_via_turn_server(context, (struct sockaddr *)&msg->net_addr, msg->net_addrlen)) {
1533 			if (ms_turn_context_get_state(context) >= MS_TURN_CONTEXT_STATE_CHANNEL_BOUND) {
1534 				/* Use a TURN ChannelData message */
1535 				new_msg = allocb(4, 0);
1536 				*((uint16_t *)new_msg->b_wptr) = htons(ms_turn_context_get_channel_number(context));
1537 				new_msg->b_wptr += 2;
1538 				*((uint16_t *)new_msg->b_wptr) = htons((uint16_t)msgdsize(msg));
1539 				new_msg->b_wptr += 2;
1540 				mblk_meta_copy(msg, new_msg);
1541 				concatb(new_msg, dupmsg(msg));
1542 				msg = new_msg;
1543 				context->stats.nb_sent_channel_msg++;
1544 			} else {
1545 				/* Use a TURN send indication to encapsulate the data to be sent */
1546 				struct sockaddr_storage realto;
1547 				socklen_t realtolen = sizeof(realto);
1548 				MSStunAddress stun_addr;
1549 				char *buf = NULL;
1550 				size_t len;
1551 				uint8_t *data;
1552 				uint16_t datalen;
1553 				msgpullup(msg, -1);
1554 				datalen = (uint16_t)(msg->b_wptr - msg->b_rptr);
1555 				bctbx_sockaddr_ipv6_to_ipv4(to, (struct sockaddr *)&realto, &realtolen);
1556 				ms_sockaddr_to_stun_address((struct sockaddr *)&realto, &stun_addr);
1557 				stun_msg = ms_turn_send_indication_create(stun_addr);
1558 				data = ms_malloc(datalen);
1559 				memcpy(data, msg->b_rptr, datalen);
1560 				ms_stun_message_set_data(stun_msg, data, datalen);
1561 				msg->b_rptr = msg->b_wptr;
1562 				len = ms_stun_message_encode(stun_msg, &buf);
1563 				msgappend(msg, buf, len, FALSE);
1564 				ms_free(buf);
1565 				context->stats.nb_send_indication++;
1566 			}
1567 			to = (const struct sockaddr *)context->turn_server_addr;
1568 			tolen = context->turn_server_addrlen;
1569 		}
1570 		ret = rtp_session_sendto(context->rtp_session, context->type == MS_TURN_CONTEXT_TYPE_RTP, msg, flags, to, tolen);
1571 	}
1572 	if (stun_msg != NULL) ms_stun_message_destroy(stun_msg);
1573 	if (new_msg != NULL) {
1574 		freemsg(new_msg);
1575 	}
1576 	return ret;
1577 }
1578 
ms_turn_rtp_endpoint_close(RtpTransport * rtptp)1579 static void ms_turn_rtp_endpoint_close(RtpTransport *rtptp) {
1580 	MSTurnContext *context = (MSTurnContext *)rtptp->data;
1581 	if (context != NULL) context->rtp_session = NULL;
1582 }
1583 
ms_turn_rtp_endpoint_destroy(RtpTransport * rtptp)1584 static void ms_turn_rtp_endpoint_destroy(RtpTransport *rtptp) {
1585 	ms_free(rtptp);
1586 }
1587 
ms_turn_context_create_endpoint(MSTurnContext * context)1588 RtpTransport * ms_turn_context_create_endpoint(MSTurnContext *context) {
1589 	RtpTransport *rtptp = ms_new0(RtpTransport, 1);
1590 	rtptp->t_getsocket = NULL;
1591 	rtptp->t_recvfrom = ms_turn_rtp_endpoint_recvfrom;
1592 	rtptp->t_sendto = ms_turn_rtp_endpoint_sendto;
1593 	rtptp->t_close = ms_turn_rtp_endpoint_close;
1594 	rtptp->t_destroy = ms_turn_rtp_endpoint_destroy;
1595 	rtptp->data = context;
1596 	context->endpoint = rtptp;
1597 	return rtptp;
1598 }
1599