1 /**
2  * FreeRDP: A Remote Desktop Protocol Implementation
3  * T.125 Multipoint Communication Service (MCS) Protocol
4  *
5  * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6  * Copyright 2015 Thincast Technologies GmbH
7  * Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
8  * Copyright 2017 Armin Novak <armin.novak@thincast.com>
9  * Copyright 2017 Thincast Technologies GmbH
10  *
11  * Licensed under the Apache License, Version 2.0 (the "License");
12  * you may not use this file except in compliance with the License.
13  * You may obtain a copy of the License at
14  *
15  *     http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  */
23 
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27 
28 #include <winpr/crt.h>
29 #include <freerdp/log.h>
30 
31 #include "gcc.h"
32 
33 #include "mcs.h"
34 #include "tpdu.h"
35 #include "tpkt.h"
36 #include "client.h"
37 #include "connection.h"
38 
39 #define TAG FREERDP_TAG("core")
40 
41 /**
42  * T.125 MCS is defined in:
43  *
44  * http://www.itu.int/rec/T-REC-T.125-199802-I/
45  * ITU-T T.125 Multipoint Communication Service Protocol Specification
46  */
47 
48 /**
49  * Connect-Initial ::= [APPLICATION 101] IMPLICIT SEQUENCE
50  * {
51  * 	callingDomainSelector		OCTET_STRING,
52  * 	calledDomainSelector		OCTET_STRING,
53  * 	upwardFlag			BOOLEAN,
54  * 	targetParameters		DomainParameters,
55  * 	minimumParameters		DomainParameters,
56  * 	maximumParameters		DomainParameters,
57  * 	userData			OCTET_STRING
58  * }
59  *
60  * DomainParameters ::= SEQUENCE
61  * {
62  * 	maxChannelIds			INTEGER (0..MAX),
63  * 	maxUserIds			INTEGER (0..MAX),
64  * 	maxTokenIds			INTEGER (0..MAX),
65  * 	numPriorities			INTEGER (0..MAX),
66  * 	minThroughput			INTEGER (0..MAX),
67  * 	maxHeight			INTEGER (0..MAX),
68  * 	maxMCSPDUsize			INTEGER (0..MAX),
69  * 	protocolVersion			INTEGER (0..MAX)
70  * }
71  *
72  * Connect-Response ::= [APPLICATION 102] IMPLICIT SEQUENCE
73  * {
74  * 	result				Result,
75  * 	calledConnectId			INTEGER (0..MAX),
76  * 	domainParameters		DomainParameters,
77  * 	userData			OCTET_STRING
78  * }
79  *
80  * Result ::= ENUMERATED
81  * {
82  * 	rt-successful			(0),
83  * 	rt-domain-merging		(1),
84  * 	rt-domain-not-hierarchical	(2),
85  * 	rt-no-such-channel		(3),
86  * 	rt-no-such-domain		(4),
87  * 	rt-no-such-user			(5),
88  * 	rt-not-admitted			(6),
89  * 	rt-other-user-id		(7),
90  * 	rt-parameters-unacceptable	(8),
91  * 	rt-token-not-available		(9),
92  * 	rt-token-not-possessed		(10),
93  * 	rt-too-many-channels		(11),
94  * 	rt-too-many-tokens		(12),
95  * 	rt-too-many-users		(13),
96  * 	rt-unspecified-failure		(14),
97  * 	rt-user-rejected		(15)
98  * }
99  *
100  * ErectDomainRequest ::= [APPLICATION 1] IMPLICIT SEQUENCE
101  * {
102  * 	subHeight			INTEGER (0..MAX),
103  * 	subInterval			INTEGER (0..MAX)
104  * }
105  *
106  * AttachUserRequest ::= [APPPLICATION 10] IMPLICIT SEQUENCE
107  * {
108  * }
109  *
110  * AttachUserConfirm ::= [APPLICATION 11] IMPLICIT SEQUENCE
111  * {
112  * 	result				Result,
113  * 	initiator			UserId OPTIONAL
114  * }
115  *
116  * ChannelJoinRequest ::= [APPLICATION 14] IMPLICIT SEQUENCE
117  * {
118  * 	initiator			UserId,
119  * 	channelId			ChannelId
120  * }
121  *
122  * ChannelJoinConfirm ::= [APPLICATION 15] IMPLICIT SEQUENCE
123  * {
124  * 	result				Result,
125  * 	initiator			UserId,
126  * 	requested			ChannelId,
127  * 	channelId			ChannelId OPTIONAL
128  * }
129  *
130  * SendDataRequest ::= [APPLICATION 25] IMPLICIT SEQUENCE
131  * {
132  * 	initiator			UserId,
133  * 	channelId			ChannelId,
134  * 	dataPriority			DataPriority,
135  * 	segmentation			Segmentation,
136  * 	userData			OCTET_STRING
137  * }
138  *
139  * DataPriority ::= CHOICE
140  * {
141  * 	top				NULL,
142  * 	high				NULL,
143  * 	medium				NULL,
144  * 	low				NULL,
145  * 	...
146  * }
147  *
148  * Segmentation ::= BIT_STRING
149  * {
150  * 	begin				(0),
151  * 	end				(1)
152  * } (SIZE(2))
153  *
154  * SendDataIndication ::= SEQUENCE
155  * {
156  * 	initiator			UserId,
157  * 	channelId			ChannelId,
158  * 	reliability			BOOLEAN,
159  * 	domainReferenceID		INTEGER (0..65535) OPTIONAL,
160  * 	dataPriority			DataPriority,
161  * 	segmentation			Segmentation,
162  * 	userData			OCTET_STRING,
163  * 	totalDataSize			INTEGER OPTIONAL,
164  * 	nonStandard			SEQUENCE OF NonStandardParameter OPTIONAL,
165  * 	...
166  * }
167  *
168  */
169 
170 static const BYTE callingDomainSelector[1] = "\x01";
171 static const BYTE calledDomainSelector[1] = "\x01";
172 
173 /*
174 static const char* const mcs_result_enumerated[] =
175 {
176         "rt-successful",
177         "rt-domain-merging",
178         "rt-domain-not-hierarchical",
179         "rt-no-such-channel",
180         "rt-no-such-domain",
181         "rt-no-such-user",
182         "rt-not-admitted",
183         "rt-other-user-id",
184         "rt-parameters-unacceptable",
185         "rt-token-not-available",
186         "rt-token-not-possessed",
187         "rt-too-many-channels",
188         "rt-too-many-tokens",
189         "rt-too-many-users",
190         "rt-unspecified-failure",
191         "rt-user-rejected"
192 };
193 */
194 
195 static BOOL mcs_merge_domain_parameters(DomainParameters* targetParameters,
196                                         DomainParameters* minimumParameters,
197                                         DomainParameters* maximumParameters,
198                                         DomainParameters* pOutParameters);
199 
200 static BOOL mcs_write_connect_initial(wStream* s, rdpMcs* mcs, wStream* userData);
201 static BOOL mcs_write_connect_response(wStream* s, rdpMcs* mcs, wStream* userData);
202 static BOOL mcs_read_domain_mcspdu_header(wStream* s, enum DomainMCSPDU* domainMCSPDU,
203                                           UINT16* length);
204 
mcs_initialize_client_channels(rdpMcs * mcs,rdpSettings * settings)205 static int mcs_initialize_client_channels(rdpMcs* mcs, rdpSettings* settings)
206 {
207 	UINT32 index;
208 
209 	if (!mcs || !settings)
210 		return -1;
211 
212 	mcs->channelCount = settings->ChannelCount;
213 
214 	if (mcs->channelCount > mcs->channelMaxCount)
215 		mcs->channelCount = mcs->channelMaxCount;
216 
217 	ZeroMemory(mcs->channels, sizeof(rdpMcsChannel) * mcs->channelMaxCount);
218 
219 	for (index = 0; index < mcs->channelCount; index++)
220 	{
221 		CopyMemory(mcs->channels[index].Name, settings->ChannelDefArray[index].name, 8);
222 		mcs->channels[index].options = settings->ChannelDefArray[index].options;
223 	}
224 
225 	return 0;
226 }
227 
228 /**
229  * Read a DomainMCSPDU header.
230  * @param s stream
231  * @param domainMCSPDU DomainMCSPDU type
232  * @param length TPKT length
233  * @return
234  */
235 
mcs_read_domain_mcspdu_header(wStream * s,enum DomainMCSPDU * domainMCSPDU,UINT16 * length)236 BOOL mcs_read_domain_mcspdu_header(wStream* s, enum DomainMCSPDU* domainMCSPDU, UINT16* length)
237 {
238 	UINT16 li;
239 	BYTE choice;
240 	enum DomainMCSPDU MCSPDU;
241 
242 	if (!s || !domainMCSPDU || !length)
243 		return FALSE;
244 
245 	if (!tpkt_read_header(s, length))
246 		return FALSE;
247 
248 	if (!tpdu_read_data(s, &li, *length))
249 		return FALSE;
250 
251 	MCSPDU = *domainMCSPDU;
252 
253 	if (!per_read_choice(s, &choice))
254 		return FALSE;
255 
256 	*domainMCSPDU = (choice >> 2);
257 
258 	if (*domainMCSPDU != MCSPDU)
259 		return FALSE;
260 
261 	return TRUE;
262 }
263 
264 /**
265  * Write a DomainMCSPDU header.
266  * @param s stream
267  * @param domainMCSPDU DomainMCSPDU type
268  * @param length TPKT length
269  */
270 
mcs_write_domain_mcspdu_header(wStream * s,enum DomainMCSPDU domainMCSPDU,UINT16 length,BYTE options)271 void mcs_write_domain_mcspdu_header(wStream* s, enum DomainMCSPDU domainMCSPDU, UINT16 length,
272                                     BYTE options)
273 {
274 	tpkt_write_header(s, length);
275 	tpdu_write_data(s);
276 	per_write_choice(s, (BYTE)((domainMCSPDU << 2) | options));
277 }
278 
279 /**
280  * Initialize MCS Domain Parameters.
281  * @param domainParameters domain parameters
282  * @param maxChannelIds max channel ids
283  * @param maxUserIds max user ids
284  * @param maxTokenIds max token ids
285  * @param maxMCSPDUsize max MCS PDU size
286  */
287 
mcs_init_domain_parameters(DomainParameters * domainParameters,UINT32 maxChannelIds,UINT32 maxUserIds,UINT32 maxTokenIds,UINT32 maxMCSPDUsize)288 static BOOL mcs_init_domain_parameters(DomainParameters* domainParameters, UINT32 maxChannelIds,
289                                        UINT32 maxUserIds, UINT32 maxTokenIds, UINT32 maxMCSPDUsize)
290 {
291 	if (!domainParameters)
292 		return FALSE;
293 
294 	domainParameters->maxChannelIds = maxChannelIds;
295 	domainParameters->maxUserIds = maxUserIds;
296 	domainParameters->maxTokenIds = maxTokenIds;
297 	domainParameters->maxMCSPDUsize = maxMCSPDUsize;
298 	domainParameters->numPriorities = 1;
299 	domainParameters->minThroughput = 0;
300 	domainParameters->maxHeight = 1;
301 	domainParameters->protocolVersion = 2;
302 	return TRUE;
303 }
304 
305 /**
306  * Read MCS Domain Parameters.
307  * @param s stream
308  * @param domainParameters domain parameters
309  */
310 
mcs_read_domain_parameters(wStream * s,DomainParameters * domainParameters)311 static BOOL mcs_read_domain_parameters(wStream* s, DomainParameters* domainParameters)
312 {
313 	size_t length;
314 
315 	if (!s || !domainParameters)
316 		return FALSE;
317 
318 	return ber_read_sequence_tag(s, &length) &&
319 	       ber_read_integer(s, &(domainParameters->maxChannelIds)) &&
320 	       ber_read_integer(s, &(domainParameters->maxUserIds)) &&
321 	       ber_read_integer(s, &(domainParameters->maxTokenIds)) &&
322 	       ber_read_integer(s, &(domainParameters->numPriorities)) &&
323 	       ber_read_integer(s, &(domainParameters->minThroughput)) &&
324 	       ber_read_integer(s, &(domainParameters->maxHeight)) &&
325 	       ber_read_integer(s, &(domainParameters->maxMCSPDUsize)) &&
326 	       ber_read_integer(s, &(domainParameters->protocolVersion));
327 }
328 
329 /**
330  * Write MCS Domain Parameters.
331  * @param s stream
332  * @param domainParameters domain parameters
333  */
334 
mcs_write_domain_parameters(wStream * s,DomainParameters * domainParameters)335 static BOOL mcs_write_domain_parameters(wStream* s, DomainParameters* domainParameters)
336 {
337 	size_t length;
338 	wStream* tmps;
339 
340 	if (!s || !domainParameters)
341 		return FALSE;
342 
343 	tmps = Stream_New(NULL, Stream_Capacity(s));
344 
345 	if (!tmps)
346 	{
347 		WLog_ERR(TAG, "Stream_New failed!");
348 		return FALSE;
349 	}
350 
351 	ber_write_integer(tmps, domainParameters->maxChannelIds);
352 	ber_write_integer(tmps, domainParameters->maxUserIds);
353 	ber_write_integer(tmps, domainParameters->maxTokenIds);
354 	ber_write_integer(tmps, domainParameters->numPriorities);
355 	ber_write_integer(tmps, domainParameters->minThroughput);
356 	ber_write_integer(tmps, domainParameters->maxHeight);
357 	ber_write_integer(tmps, domainParameters->maxMCSPDUsize);
358 	ber_write_integer(tmps, domainParameters->protocolVersion);
359 	length = Stream_GetPosition(tmps);
360 	ber_write_sequence_tag(s, length);
361 	Stream_Write(s, Stream_Buffer(tmps), length);
362 	Stream_Free(tmps, TRUE);
363 	return TRUE;
364 }
365 
366 #ifdef DEBUG_MCS
367 /**
368  * Print MCS Domain Parameters.
369  * @param domainParameters domain parameters
370  */
371 
mcs_print_domain_parameters(DomainParameters * domainParameters)372 static void mcs_print_domain_parameters(DomainParameters* domainParameters)
373 {
374 	WLog_INFO(TAG, "DomainParameters {");
375 
376 	if (domainParameters)
377 	{
378 		WLog_INFO(TAG, "\tmaxChannelIds:%" PRIu32 "", domainParameters->maxChannelIds);
379 		WLog_INFO(TAG, "\tmaxUserIds:%" PRIu32 "", domainParameters->maxUserIds);
380 		WLog_INFO(TAG, "\tmaxTokenIds:%" PRIu32 "", domainParameters->maxTokenIds);
381 		WLog_INFO(TAG, "\tnumPriorities:%" PRIu32 "", domainParameters->numPriorities);
382 		WLog_INFO(TAG, "\tminThroughput:%" PRIu32 "", domainParameters->minThroughput);
383 		WLog_INFO(TAG, "\tmaxHeight:%" PRIu32 "", domainParameters->maxHeight);
384 		WLog_INFO(TAG, "\tmaxMCSPDUsize:%" PRIu32 "", domainParameters->maxMCSPDUsize);
385 		WLog_INFO(TAG, "\tprotocolVersion:%" PRIu32 "", domainParameters->protocolVersion);
386 	}
387 	else
388 		WLog_INFO(TAG, "\tdomainParameters=%p", domainParameters);
389 
390 	WLog_INFO(TAG, "}");
391 }
392 #endif
393 
394 /**
395  * Merge MCS Domain Parameters.
396  * @param domainParameters target parameters
397  * @param domainParameters minimum parameters
398  * @param domainParameters maximum parameters
399  * @param domainParameters output parameters
400  */
401 
mcs_merge_domain_parameters(DomainParameters * targetParameters,DomainParameters * minimumParameters,DomainParameters * maximumParameters,DomainParameters * pOutParameters)402 BOOL mcs_merge_domain_parameters(DomainParameters* targetParameters,
403                                  DomainParameters* minimumParameters,
404                                  DomainParameters* maximumParameters,
405                                  DomainParameters* pOutParameters)
406 {
407 	/* maxChannelIds */
408 	if (!targetParameters || !minimumParameters || !maximumParameters || !pOutParameters)
409 		return FALSE;
410 
411 	if (targetParameters->maxChannelIds >= 4)
412 	{
413 		pOutParameters->maxChannelIds = targetParameters->maxChannelIds;
414 	}
415 	else if (maximumParameters->maxChannelIds >= 4)
416 	{
417 		pOutParameters->maxChannelIds = 4;
418 	}
419 	else
420 	{
421 		return FALSE;
422 	}
423 
424 	/* maxUserIds */
425 
426 	if (targetParameters->maxUserIds >= 3)
427 	{
428 		pOutParameters->maxUserIds = targetParameters->maxUserIds;
429 	}
430 	else if (maximumParameters->maxUserIds >= 3)
431 	{
432 		pOutParameters->maxUserIds = 3;
433 	}
434 	else
435 	{
436 		return FALSE;
437 	}
438 
439 	/* maxTokenIds */
440 	pOutParameters->maxTokenIds = targetParameters->maxTokenIds;
441 
442 	/* numPriorities */
443 
444 	if (minimumParameters->numPriorities <= 1)
445 	{
446 		pOutParameters->numPriorities = 1;
447 	}
448 	else
449 	{
450 		return FALSE;
451 	}
452 
453 	/* minThroughput */
454 	pOutParameters->minThroughput = targetParameters->minThroughput;
455 
456 	/* maxHeight */
457 
458 	if ((targetParameters->maxHeight == 1) || (minimumParameters->maxHeight <= 1))
459 	{
460 		pOutParameters->maxHeight = 1;
461 	}
462 	else
463 	{
464 		return FALSE;
465 	}
466 
467 	/* maxMCSPDUsize */
468 
469 	if (targetParameters->maxMCSPDUsize >= 1024)
470 	{
471 		if (targetParameters->maxMCSPDUsize <= 65528)
472 		{
473 			pOutParameters->maxMCSPDUsize = targetParameters->maxMCSPDUsize;
474 		}
475 		else if ((minimumParameters->maxMCSPDUsize >= 124) &&
476 		         (minimumParameters->maxMCSPDUsize <= 65528))
477 		{
478 			pOutParameters->maxMCSPDUsize = 65528;
479 		}
480 		else
481 		{
482 			return FALSE;
483 		}
484 	}
485 	else
486 	{
487 		if (maximumParameters->maxMCSPDUsize >= 124)
488 		{
489 			pOutParameters->maxMCSPDUsize = maximumParameters->maxMCSPDUsize;
490 		}
491 		else
492 		{
493 			return FALSE;
494 		}
495 	}
496 
497 	/* protocolVersion */
498 
499 	if ((targetParameters->protocolVersion == 2) ||
500 	    ((minimumParameters->protocolVersion <= 2) && (maximumParameters->protocolVersion >= 2)))
501 	{
502 		pOutParameters->protocolVersion = 2;
503 	}
504 	else
505 	{
506 		return FALSE;
507 	}
508 
509 	return TRUE;
510 }
511 
512 /**
513  * Read an MCS Connect Initial PDU.\n
514  * @msdn{cc240508}
515  * @param mcs MCS module
516  * @param s stream
517  */
518 
mcs_recv_connect_initial(rdpMcs * mcs,wStream * s)519 BOOL mcs_recv_connect_initial(rdpMcs* mcs, wStream* s)
520 {
521 	UINT16 li;
522 	size_t length;
523 	BOOL upwardFlag;
524 	UINT16 tlength;
525 
526 	if (!mcs || !s)
527 		return FALSE;
528 
529 	if (!tpkt_read_header(s, &tlength))
530 		return FALSE;
531 
532 	if (!tpdu_read_data(s, &li, tlength))
533 		return FALSE;
534 
535 	if (!ber_read_application_tag(s, MCS_TYPE_CONNECT_INITIAL, &length))
536 		return FALSE;
537 
538 	/* callingDomainSelector (OCTET_STRING) */
539 	if (!ber_read_octet_string_tag(s, &length) || (Stream_GetRemainingLength(s)) < length)
540 		return FALSE;
541 
542 	Stream_Seek(s, length);
543 
544 	/* calledDomainSelector (OCTET_STRING) */
545 	if (!ber_read_octet_string_tag(s, &length) || (Stream_GetRemainingLength(s)) < length)
546 		return FALSE;
547 
548 	Stream_Seek(s, length);
549 
550 	/* upwardFlag (BOOLEAN) */
551 	if (!ber_read_BOOL(s, &upwardFlag))
552 		return FALSE;
553 
554 	/* targetParameters (DomainParameters) */
555 	if (!mcs_read_domain_parameters(s, &mcs->targetParameters))
556 		return FALSE;
557 
558 	/* minimumParameters (DomainParameters) */
559 	if (!mcs_read_domain_parameters(s, &mcs->minimumParameters))
560 		return FALSE;
561 
562 	/* maximumParameters (DomainParameters) */
563 	if (!mcs_read_domain_parameters(s, &mcs->maximumParameters))
564 		return FALSE;
565 
566 	if (!ber_read_octet_string_tag(s, &length) || (Stream_GetRemainingLength(s)) < length)
567 		return FALSE;
568 
569 	if (!gcc_read_conference_create_request(s, mcs))
570 		return FALSE;
571 
572 	if (!mcs_merge_domain_parameters(&mcs->targetParameters, &mcs->minimumParameters,
573 	                                 &mcs->maximumParameters, &mcs->domainParameters))
574 		return FALSE;
575 
576 	return tpkt_ensure_stream_consumed(s, tlength);
577 }
578 
579 /**
580  * Write an MCS Connect Initial PDU.\n
581  * @msdn{cc240508}
582  * @param s stream
583  * @param mcs MCS module
584  * @param user_data GCC Conference Create Request
585  */
586 
mcs_write_connect_initial(wStream * s,rdpMcs * mcs,wStream * userData)587 BOOL mcs_write_connect_initial(wStream* s, rdpMcs* mcs, wStream* userData)
588 {
589 	size_t length;
590 	wStream* tmps;
591 	BOOL ret = FALSE;
592 
593 	if (!s || !mcs || !userData)
594 		return FALSE;
595 
596 	tmps = Stream_New(NULL, Stream_Capacity(s));
597 
598 	if (!tmps)
599 	{
600 		WLog_ERR(TAG, "Stream_New failed!");
601 		return FALSE;
602 	}
603 
604 	/* callingDomainSelector (OCTET_STRING) */
605 	ber_write_octet_string(tmps, callingDomainSelector, sizeof(callingDomainSelector));
606 	/* calledDomainSelector (OCTET_STRING) */
607 	ber_write_octet_string(tmps, calledDomainSelector, sizeof(calledDomainSelector));
608 	/* upwardFlag (BOOLEAN) */
609 	ber_write_BOOL(tmps, TRUE);
610 
611 	/* targetParameters (DomainParameters) */
612 	if (!mcs_write_domain_parameters(tmps, &mcs->targetParameters))
613 		goto out;
614 
615 	/* minimumParameters (DomainParameters) */
616 	if (!mcs_write_domain_parameters(tmps, &mcs->minimumParameters))
617 		goto out;
618 
619 	/* maximumParameters (DomainParameters) */
620 	if (!mcs_write_domain_parameters(tmps, &mcs->maximumParameters))
621 		goto out;
622 
623 	/* userData (OCTET_STRING) */
624 	ber_write_octet_string(tmps, Stream_Buffer(userData), Stream_GetPosition(userData));
625 	length = Stream_GetPosition(tmps);
626 	/* Connect-Initial (APPLICATION 101, IMPLICIT SEQUENCE) */
627 	ber_write_application_tag(s, MCS_TYPE_CONNECT_INITIAL, length);
628 	Stream_Write(s, Stream_Buffer(tmps), length);
629 	ret = TRUE;
630 out:
631 	Stream_Free(tmps, TRUE);
632 	return ret;
633 }
634 
635 /**
636  * Write an MCS Connect Response PDU.\n
637  * @msdn{cc240508}
638  * @param s stream
639  * @param mcs MCS module
640  * @param user_data GCC Conference Create Response
641  */
642 
mcs_write_connect_response(wStream * s,rdpMcs * mcs,wStream * userData)643 BOOL mcs_write_connect_response(wStream* s, rdpMcs* mcs, wStream* userData)
644 {
645 	size_t length;
646 	wStream* tmps;
647 	BOOL ret = FALSE;
648 
649 	if (!s || !mcs || !userData)
650 		return FALSE;
651 
652 	tmps = Stream_New(NULL, Stream_Capacity(s));
653 
654 	if (!tmps)
655 	{
656 		WLog_ERR(TAG, "Stream_New failed!");
657 		return FALSE;
658 	}
659 
660 	ber_write_enumerated(tmps, 0, MCS_Result_enum_length);
661 	ber_write_integer(tmps, 0); /* calledConnectId */
662 
663 	if (!mcs_write_domain_parameters(tmps, &(mcs->domainParameters)))
664 		goto out;
665 
666 	/* userData (OCTET_STRING) */
667 	ber_write_octet_string(tmps, Stream_Buffer(userData), Stream_GetPosition(userData));
668 	length = Stream_GetPosition(tmps);
669 	ber_write_application_tag(s, MCS_TYPE_CONNECT_RESPONSE, length);
670 	Stream_Write(s, Stream_Buffer(tmps), length);
671 	ret = TRUE;
672 out:
673 	Stream_Free(tmps, TRUE);
674 	return ret;
675 }
676 
677 /**
678  * Send MCS Connect Initial.\n
679  * @msdn{cc240508}
680  * @param mcs mcs module
681  */
682 
mcs_send_connect_initial(rdpMcs * mcs)683 BOOL mcs_send_connect_initial(rdpMcs* mcs)
684 {
685 	int status = -1;
686 	size_t length;
687 	wStream* s = NULL;
688 	size_t bm, em;
689 	wStream* gcc_CCrq = NULL;
690 	wStream* client_data = NULL;
691 
692 	if (!mcs)
693 		return FALSE;
694 
695 	mcs_initialize_client_channels(mcs, mcs->settings);
696 	client_data = Stream_New(NULL, 512);
697 
698 	if (!client_data)
699 	{
700 		WLog_ERR(TAG, "Stream_New failed!");
701 		return FALSE;
702 	}
703 
704 	if (!gcc_write_client_data_blocks(client_data, mcs))
705 		goto out;
706 
707 	gcc_CCrq = Stream_New(NULL, 1024);
708 
709 	if (!gcc_CCrq)
710 	{
711 		WLog_ERR(TAG, "Stream_New failed!");
712 		goto out;
713 	}
714 
715 	gcc_write_conference_create_request(gcc_CCrq, client_data);
716 	length = Stream_GetPosition(gcc_CCrq) + 7;
717 	s = Stream_New(NULL, 1024 + length);
718 
719 	if (!s)
720 	{
721 		WLog_ERR(TAG, "Stream_New failed!");
722 		goto out;
723 	}
724 
725 	bm = Stream_GetPosition(s);
726 	Stream_Seek(s, 7);
727 
728 	if (!mcs_write_connect_initial(s, mcs, gcc_CCrq))
729 	{
730 		WLog_ERR(TAG, "mcs_write_connect_initial failed!");
731 		goto out;
732 	}
733 
734 	em = Stream_GetPosition(s);
735 	length = (em - bm);
736 	if (length > UINT16_MAX)
737 		goto out;
738 	Stream_SetPosition(s, bm);
739 	if (!tpkt_write_header(s, (UINT16)length))
740 		goto out;
741 	tpdu_write_data(s);
742 	Stream_SetPosition(s, em);
743 	Stream_SealLength(s);
744 	status = transport_write(mcs->transport, s);
745 out:
746 	Stream_Free(s, TRUE);
747 	Stream_Free(gcc_CCrq, TRUE);
748 	Stream_Free(client_data, TRUE);
749 	return (status < 0 ? FALSE : TRUE);
750 }
751 
752 /**
753  * Read MCS Connect Response.\n
754  * @msdn{cc240501}
755  * @param mcs mcs module
756  */
757 
mcs_recv_connect_response(rdpMcs * mcs,wStream * s)758 BOOL mcs_recv_connect_response(rdpMcs* mcs, wStream* s)
759 {
760 	size_t length;
761 	UINT16 tlength;
762 	BYTE result;
763 	UINT16 li;
764 	UINT32 calledConnectId;
765 
766 	if (!mcs || !s)
767 		return FALSE;
768 
769 	if (!tpkt_read_header(s, &tlength))
770 		return FALSE;
771 
772 	if (!tpdu_read_data(s, &li, tlength))
773 		return FALSE;
774 
775 	if (!ber_read_application_tag(s, MCS_TYPE_CONNECT_RESPONSE, &length) ||
776 	    !ber_read_enumerated(s, &result, MCS_Result_enum_length) ||
777 	    !ber_read_integer(s, &calledConnectId) ||
778 	    !mcs_read_domain_parameters(s, &(mcs->domainParameters)) ||
779 	    !ber_read_octet_string_tag(s, &length))
780 	{
781 		return FALSE;
782 	}
783 
784 	if (!gcc_read_conference_create_response(s, mcs))
785 	{
786 		WLog_ERR(TAG, "gcc_read_conference_create_response failed");
787 		return FALSE;
788 	}
789 
790 	return tpkt_ensure_stream_consumed(s, tlength);
791 }
792 
793 /**
794  * Send MCS Connect Response.\n
795  * @msdn{cc240501}
796  * @param mcs mcs module
797  */
798 
mcs_send_connect_response(rdpMcs * mcs)799 BOOL mcs_send_connect_response(rdpMcs* mcs)
800 {
801 	size_t length;
802 	int status = -1;
803 	wStream* s = NULL;
804 	size_t bm, em;
805 	wStream* gcc_CCrsp = NULL;
806 	wStream* server_data = NULL;
807 
808 	if (!mcs)
809 		return FALSE;
810 
811 	server_data = Stream_New(NULL, 512);
812 
813 	if (!server_data)
814 	{
815 		WLog_ERR(TAG, "Stream_New failed!");
816 		return FALSE;
817 	}
818 
819 	if (!gcc_write_server_data_blocks(server_data, mcs))
820 		goto out;
821 
822 	gcc_CCrsp = Stream_New(NULL, 512 + Stream_Capacity(server_data));
823 
824 	if (!gcc_CCrsp)
825 	{
826 		WLog_ERR(TAG, "Stream_New failed!");
827 		goto out;
828 	}
829 
830 	gcc_write_conference_create_response(gcc_CCrsp, server_data);
831 	length = Stream_GetPosition(gcc_CCrsp) + 7;
832 	s = Stream_New(NULL, length + 1024);
833 
834 	if (!s)
835 	{
836 		WLog_ERR(TAG, "Stream_New failed!");
837 		goto out;
838 	}
839 
840 	bm = Stream_GetPosition(s);
841 	Stream_Seek(s, 7);
842 
843 	if (!mcs_write_connect_response(s, mcs, gcc_CCrsp))
844 		goto out;
845 
846 	em = Stream_GetPosition(s);
847 	length = (em - bm);
848 	if (length > UINT16_MAX)
849 		goto out;
850 	Stream_SetPosition(s, bm);
851 	if (!tpkt_write_header(s, (UINT16)length))
852 		goto out;
853 	tpdu_write_data(s);
854 	Stream_SetPosition(s, em);
855 	Stream_SealLength(s);
856 	status = transport_write(mcs->transport, s);
857 out:
858 	Stream_Free(s, TRUE);
859 	Stream_Free(gcc_CCrsp, TRUE);
860 	Stream_Free(server_data, TRUE);
861 	return (status < 0) ? FALSE : TRUE;
862 }
863 
864 /**
865  * Read MCS Erect Domain Request.\n
866  * @msdn{cc240523}
867  * @param mcs
868  * @param s stream
869  */
870 
mcs_recv_erect_domain_request(rdpMcs * mcs,wStream * s)871 BOOL mcs_recv_erect_domain_request(rdpMcs* mcs, wStream* s)
872 {
873 	UINT16 length;
874 	UINT32 subHeight;
875 	UINT32 subInterval;
876 	enum DomainMCSPDU MCSPDU;
877 
878 	if (!mcs || !s)
879 		return FALSE;
880 
881 	MCSPDU = DomainMCSPDU_ErectDomainRequest;
882 
883 	if (!mcs_read_domain_mcspdu_header(s, &MCSPDU, &length))
884 		return FALSE;
885 
886 	if (!per_read_integer(s, &subHeight)) /* subHeight (INTEGER) */
887 		return FALSE;
888 
889 	if (!per_read_integer(s, &subInterval)) /* subInterval (INTEGER) */
890 		return FALSE;
891 
892 	return tpkt_ensure_stream_consumed(s, length);
893 }
894 
895 /**
896  * Send MCS Erect Domain Request.\n
897  * @msdn{cc240523}
898  * @param mcs
899  */
900 
mcs_send_erect_domain_request(rdpMcs * mcs)901 BOOL mcs_send_erect_domain_request(rdpMcs* mcs)
902 {
903 	wStream* s;
904 	int status;
905 	UINT16 length = 12;
906 
907 	if (!mcs)
908 		return FALSE;
909 
910 	s = Stream_New(NULL, length);
911 
912 	if (!s)
913 	{
914 		WLog_ERR(TAG, "Stream_New failed!");
915 		return FALSE;
916 	}
917 
918 	mcs_write_domain_mcspdu_header(s, DomainMCSPDU_ErectDomainRequest, length, 0);
919 	per_write_integer(s, 0); /* subHeight (INTEGER) */
920 	per_write_integer(s, 0); /* subInterval (INTEGER) */
921 	Stream_SealLength(s);
922 	status = transport_write(mcs->transport, s);
923 	Stream_Free(s, TRUE);
924 	return (status < 0) ? FALSE : TRUE;
925 }
926 
927 /**
928  * Read MCS Attach User Request.\n
929  * @msdn{cc240524}
930  * @param mcs mcs module
931  * @param s stream
932  */
933 
mcs_recv_attach_user_request(rdpMcs * mcs,wStream * s)934 BOOL mcs_recv_attach_user_request(rdpMcs* mcs, wStream* s)
935 {
936 	UINT16 length;
937 	enum DomainMCSPDU MCSPDU;
938 
939 	if (!mcs || !s)
940 		return FALSE;
941 
942 	MCSPDU = DomainMCSPDU_AttachUserRequest;
943 	if (!mcs_read_domain_mcspdu_header(s, &MCSPDU, &length))
944 		return FALSE;
945 	return tpkt_ensure_stream_consumed(s, length);
946 }
947 
948 /**
949  * Send MCS Attach User Request.\n
950  * @msdn{cc240524}
951  * @param mcs mcs module
952  */
953 
mcs_send_attach_user_request(rdpMcs * mcs)954 BOOL mcs_send_attach_user_request(rdpMcs* mcs)
955 {
956 	wStream* s;
957 	int status;
958 	UINT16 length = 8;
959 
960 	if (!mcs)
961 		return FALSE;
962 
963 	s = Stream_New(NULL, length);
964 
965 	if (!s)
966 	{
967 		WLog_ERR(TAG, "Stream_New failed!");
968 		return FALSE;
969 	}
970 
971 	mcs_write_domain_mcspdu_header(s, DomainMCSPDU_AttachUserRequest, length, 0);
972 	Stream_SealLength(s);
973 	status = transport_write(mcs->transport, s);
974 	Stream_Free(s, TRUE);
975 	return (status < 0) ? FALSE : TRUE;
976 }
977 
978 /**
979  * Read MCS Attach User Confirm.\n
980  * @msdn{cc240525}
981  * @param mcs mcs module
982  */
983 
mcs_recv_attach_user_confirm(rdpMcs * mcs,wStream * s)984 BOOL mcs_recv_attach_user_confirm(rdpMcs* mcs, wStream* s)
985 {
986 	BYTE result;
987 	UINT16 length;
988 	enum DomainMCSPDU MCSPDU;
989 
990 	if (!mcs || !s)
991 		return FALSE;
992 
993 	MCSPDU = DomainMCSPDU_AttachUserConfirm;
994 	if (!mcs_read_domain_mcspdu_header(s, &MCSPDU, &length))
995 		return FALSE;
996 	if (!per_read_enumerated(s, &result, MCS_Result_enum_length)) /* result */
997 		return FALSE;
998 	if (!per_read_integer16(s, &(mcs->userId), MCS_BASE_CHANNEL_ID)) /* initiator (UserId) */
999 		return FALSE;
1000 	return tpkt_ensure_stream_consumed(s, length);
1001 }
1002 
1003 /**
1004  * Send MCS Attach User Confirm.\n
1005  * @msdn{cc240525}
1006  * @param mcs mcs module
1007  */
1008 
mcs_send_attach_user_confirm(rdpMcs * mcs)1009 BOOL mcs_send_attach_user_confirm(rdpMcs* mcs)
1010 {
1011 	wStream* s;
1012 	int status;
1013 	UINT16 length = 11;
1014 
1015 	if (!mcs)
1016 		return FALSE;
1017 
1018 	s = Stream_New(NULL, length);
1019 
1020 	if (!s)
1021 	{
1022 		WLog_ERR(TAG, "Stream_New failed!");
1023 		return FALSE;
1024 	}
1025 
1026 	mcs->userId = mcs->baseChannelId++;
1027 	mcs_write_domain_mcspdu_header(s, DomainMCSPDU_AttachUserConfirm, length, 2);
1028 	per_write_enumerated(s, 0, MCS_Result_enum_length);       /* result */
1029 	per_write_integer16(s, mcs->userId, MCS_BASE_CHANNEL_ID); /* initiator (UserId) */
1030 	Stream_SealLength(s);
1031 	status = transport_write(mcs->transport, s);
1032 	Stream_Free(s, TRUE);
1033 	return (status < 0) ? FALSE : TRUE;
1034 }
1035 
1036 /**
1037  * Read MCS Channel Join Request.\n
1038  * @msdn{cc240526}
1039  * @param mcs mcs module
1040  * @param s stream
1041  */
1042 
mcs_recv_channel_join_request(rdpMcs * mcs,wStream * s,UINT16 * channelId)1043 BOOL mcs_recv_channel_join_request(rdpMcs* mcs, wStream* s, UINT16* channelId)
1044 {
1045 	UINT16 length;
1046 	UINT16 userId;
1047 	enum DomainMCSPDU MCSPDU;
1048 
1049 	if (!mcs || !s || !channelId)
1050 		return FALSE;
1051 
1052 	MCSPDU = DomainMCSPDU_ChannelJoinRequest;
1053 	if (!mcs_read_domain_mcspdu_header(s, &MCSPDU, &length))
1054 		return FALSE;
1055 
1056 	if (!per_read_integer16(s, &userId, MCS_BASE_CHANNEL_ID) && (userId == mcs->userId))
1057 		return FALSE;
1058 	if (!per_read_integer16(s, channelId, 0))
1059 		return FALSE;
1060 
1061 	return tpkt_ensure_stream_consumed(s, length);
1062 }
1063 
1064 /**
1065  * Send MCS Channel Join Request.\n
1066  * @msdn{cc240526}
1067  * @param mcs mcs module
1068  * @param channel_id channel id
1069  */
1070 
mcs_send_channel_join_request(rdpMcs * mcs,UINT16 channelId)1071 BOOL mcs_send_channel_join_request(rdpMcs* mcs, UINT16 channelId)
1072 {
1073 	wStream* s;
1074 	int status;
1075 	UINT16 length = 12;
1076 
1077 	if (!mcs)
1078 		return FALSE;
1079 
1080 	s = Stream_New(NULL, length);
1081 
1082 	if (!s)
1083 	{
1084 		WLog_ERR(TAG, "Stream_New failed!");
1085 		return FALSE;
1086 	}
1087 
1088 	mcs_write_domain_mcspdu_header(s, DomainMCSPDU_ChannelJoinRequest, length, 0);
1089 	per_write_integer16(s, mcs->userId, MCS_BASE_CHANNEL_ID);
1090 	per_write_integer16(s, channelId, 0);
1091 	Stream_SealLength(s);
1092 	status = transport_write(mcs->transport, s);
1093 	Stream_Free(s, TRUE);
1094 	return (status < 0) ? FALSE : TRUE;
1095 }
1096 
1097 /**
1098  * Read MCS Channel Join Confirm.\n
1099  * @msdn{cc240527}
1100  * @param mcs mcs module
1101  */
1102 
mcs_recv_channel_join_confirm(rdpMcs * mcs,wStream * s,UINT16 * channelId)1103 BOOL mcs_recv_channel_join_confirm(rdpMcs* mcs, wStream* s, UINT16* channelId)
1104 {
1105 	BOOL status;
1106 	UINT16 length;
1107 	BYTE result;
1108 	UINT16 initiator;
1109 	UINT16 requested;
1110 	enum DomainMCSPDU MCSPDU;
1111 
1112 	if (!mcs || !s || !channelId)
1113 		return FALSE;
1114 
1115 	status = TRUE;
1116 	MCSPDU = DomainMCSPDU_ChannelJoinConfirm;
1117 	if (!mcs_read_domain_mcspdu_header(s, &MCSPDU, &length))
1118 		return FALSE;
1119 
1120 	if (!per_read_enumerated(s, &result, MCS_Result_enum_length)) /* result */
1121 		return FALSE;
1122 	if (!per_read_integer16(s, &initiator, MCS_BASE_CHANNEL_ID)) /* initiator (UserId) */
1123 		return FALSE;
1124 	if (!per_read_integer16(s, &requested, 0)) /* requested (ChannelId) */
1125 		return FALSE;
1126 	if (!per_read_integer16(s, channelId, 0)) /* channelId */
1127 		return FALSE;
1128 	return tpkt_ensure_stream_consumed(s, length);
1129 }
1130 
1131 /**
1132  * Send MCS Channel Join Confirm.\n
1133  * @msdn{cc240527}
1134  * @param mcs mcs module
1135  */
1136 
mcs_send_channel_join_confirm(rdpMcs * mcs,UINT16 channelId)1137 BOOL mcs_send_channel_join_confirm(rdpMcs* mcs, UINT16 channelId)
1138 {
1139 	wStream* s;
1140 	int status;
1141 	UINT16 length = 15;
1142 
1143 	if (!mcs)
1144 		return FALSE;
1145 
1146 	s = Stream_New(NULL, length);
1147 
1148 	if (!s)
1149 	{
1150 		WLog_ERR(TAG, "Stream_New failed!");
1151 		return FALSE;
1152 	}
1153 
1154 	mcs_write_domain_mcspdu_header(s, DomainMCSPDU_ChannelJoinConfirm, length, 2);
1155 	per_write_enumerated(s, 0, MCS_Result_enum_length);       /* result */
1156 	per_write_integer16(s, mcs->userId, MCS_BASE_CHANNEL_ID); /* initiator (UserId) */
1157 	per_write_integer16(s, channelId, 0);                     /* requested (ChannelId) */
1158 	per_write_integer16(s, channelId, 0);                     /* channelId */
1159 	Stream_SealLength(s);
1160 	status = transport_write(mcs->transport, s);
1161 	Stream_Free(s, TRUE);
1162 	return (status < 0) ? FALSE : TRUE;
1163 }
1164 
1165 /**
1166  * Receive MCS Disconnect Provider Ultimatum PDU.\n
1167  * @param mcs mcs module
1168  */
1169 
mcs_recv_disconnect_provider_ultimatum(rdpMcs * mcs,wStream * s,int * reason)1170 BOOL mcs_recv_disconnect_provider_ultimatum(rdpMcs* mcs, wStream* s, int* reason)
1171 {
1172 	BYTE b1, b2;
1173 
1174 	if (!mcs || !s || !reason)
1175 		return FALSE;
1176 
1177 	/*
1178 	 * http://msdn.microsoft.com/en-us/library/cc240872.aspx:
1179 	 *
1180 	 * PER encoded (ALIGNED variant of BASIC-PER) PDU contents:
1181 	 * 21 80
1182 	 *
1183 	 * 0x21:
1184 	 * 0 - --\
1185 	 * 0 -   |
1186 	 * 1 -   | CHOICE: From DomainMCSPDU select disconnectProviderUltimatum (8)
1187 	 * 0 -   | of type DisconnectProviderUltimatum
1188 	 * 0 -   |
1189 	 * 0 - --/
1190 	 * 0 - --\
1191 	 * 1 -   |
1192 	 *       | DisconnectProviderUltimatum::reason = rn-user-requested (3)
1193 	 * 0x80: |
1194 	 * 1 - --/
1195 	 * 0 - padding
1196 	 * 0 - padding
1197 	 * 0 - padding
1198 	 * 0 - padding
1199 	 * 0 - padding
1200 	 * 0 - padding
1201 	 * 0 - padding
1202 	 */
1203 
1204 	if (Stream_GetRemainingLength(s) < 1)
1205 		return FALSE;
1206 
1207 	Stream_Rewind_UINT8(s);
1208 	Stream_Read_UINT8(s, b1);
1209 	Stream_Read_UINT8(s, b2);
1210 	*reason = ((b1 & 0x01) << 1) | (b2 >> 7);
1211 	return TRUE;
1212 }
1213 
1214 /**
1215  * Send MCS Disconnect Provider Ultimatum PDU.\n
1216  * @param mcs mcs module
1217  */
1218 
mcs_send_disconnect_provider_ultimatum(rdpMcs * mcs)1219 BOOL mcs_send_disconnect_provider_ultimatum(rdpMcs* mcs)
1220 {
1221 	wStream* s;
1222 	int status;
1223 	UINT16 length = 9;
1224 
1225 	if (!mcs)
1226 		return FALSE;
1227 
1228 	s = Stream_New(NULL, length);
1229 
1230 	if (!s)
1231 	{
1232 		WLog_ERR(TAG, "Stream_New failed!");
1233 		return FALSE;
1234 	}
1235 
1236 	mcs_write_domain_mcspdu_header(s, DomainMCSPDU_DisconnectProviderUltimatum, length, 1);
1237 	per_write_enumerated(s, 0x80, 0);
1238 	status = transport_write(mcs->transport, s);
1239 	Stream_Free(s, TRUE);
1240 	return (status < 0) ? FALSE : TRUE;
1241 }
1242 
mcs_client_begin(rdpMcs * mcs)1243 BOOL mcs_client_begin(rdpMcs* mcs)
1244 {
1245 	rdpContext* context;
1246 
1247 	if (!mcs || !mcs->transport)
1248 		return FALSE;
1249 
1250 	context = mcs->transport->context;
1251 
1252 	if (!context)
1253 		return FALSE;
1254 
1255 	if (!mcs_send_connect_initial(mcs))
1256 	{
1257 		freerdp_set_last_error_if_not(context, FREERDP_ERROR_MCS_CONNECT_INITIAL_ERROR);
1258 
1259 		WLog_ERR(TAG, "Error: unable to send MCS Connect Initial");
1260 		return FALSE;
1261 	}
1262 
1263 	rdp_client_transition_to_state(context->rdp, CONNECTION_STATE_MCS_CONNECT);
1264 	return TRUE;
1265 }
1266 
1267 /**
1268  * Instantiate new MCS module.
1269  * @param transport transport
1270  * @return new MCS module
1271  */
1272 
mcs_new(rdpTransport * transport)1273 rdpMcs* mcs_new(rdpTransport* transport)
1274 {
1275 	rdpMcs* mcs;
1276 
1277 	if (!transport)
1278 		return NULL;
1279 
1280 	mcs = (rdpMcs*)calloc(1, sizeof(rdpMcs));
1281 
1282 	if (!mcs)
1283 		return NULL;
1284 
1285 	mcs->transport = transport;
1286 	mcs->settings = transport->settings;
1287 	mcs_init_domain_parameters(&mcs->targetParameters, 34, 2, 0, 0xFFFF);
1288 	mcs_init_domain_parameters(&mcs->minimumParameters, 1, 1, 1, 0x420);
1289 	mcs_init_domain_parameters(&mcs->maximumParameters, 0xFFFF, 0xFC17, 0xFFFF, 0xFFFF);
1290 	mcs_init_domain_parameters(&mcs->domainParameters, 0, 0, 0, 0xFFFF);
1291 	mcs->channelCount = 0;
1292 	mcs->channelMaxCount = CHANNEL_MAX_COUNT;
1293 	mcs->baseChannelId = MCS_GLOBAL_CHANNEL_ID + 1;
1294 	mcs->channels = (rdpMcsChannel*)calloc(mcs->channelMaxCount, sizeof(rdpMcsChannel));
1295 
1296 	if (!mcs->channels)
1297 		goto out_free;
1298 
1299 	return mcs;
1300 out_free:
1301 	free(mcs);
1302 	return NULL;
1303 }
1304 
1305 /**
1306  * Free MCS module.
1307  * @param mcs MCS module to be freed
1308  */
1309 
mcs_free(rdpMcs * mcs)1310 void mcs_free(rdpMcs* mcs)
1311 {
1312 	if (mcs)
1313 	{
1314 		free(mcs->channels);
1315 		free(mcs);
1316 	}
1317 }
1318