1 /**
2  * FreeRDP: A Remote Desktop Protocol Implementation
3  * RDP Server Peer
4  *
5  * Copyright 2011 Vic Lee
6  * Copyright 2014 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 
25 #include <winpr/crt.h>
26 #include <winpr/winsock.h>
27 
28 #include "info.h"
29 #include "certificate.h"
30 
31 #include <freerdp/log.h>
32 
33 #include "rdp.h"
34 #include "peer.h"
35 
36 #define TAG FREERDP_TAG("core.peer")
37 
freerdp_peer_virtual_channel_open(freerdp_peer * client,const char * name,UINT32 flags)38 static HANDLE freerdp_peer_virtual_channel_open(freerdp_peer* client, const char* name,
39                                                 UINT32 flags)
40 {
41 	int length;
42 	UINT32 index;
43 	BOOL joined = FALSE;
44 	rdpMcsChannel* mcsChannel = NULL;
45 	rdpPeerChannel* peerChannel = NULL;
46 	rdpMcs* mcs = client->context->rdp->mcs;
47 
48 	if (flags & WTS_CHANNEL_OPTION_DYNAMIC)
49 		return NULL; /* not yet supported */
50 
51 	length = strnlen(name, 9);
52 
53 	if (length > 8)
54 		return NULL; /* SVC maximum name length is 8 */
55 
56 	for (index = 0; index < mcs->channelCount; index++)
57 	{
58 		mcsChannel = &(mcs->channels[index]);
59 
60 		if (!mcsChannel->joined)
61 			continue;
62 
63 		if (_strnicmp(name, mcsChannel->Name, length) == 0)
64 		{
65 			joined = TRUE;
66 			break;
67 		}
68 	}
69 
70 	if (!joined)
71 		return NULL; /* channel is not joined */
72 
73 	peerChannel = (rdpPeerChannel*)mcsChannel->handle;
74 
75 	if (peerChannel)
76 	{
77 		/* channel is already open */
78 		return (HANDLE)peerChannel;
79 	}
80 
81 	peerChannel = (rdpPeerChannel*)calloc(1, sizeof(rdpPeerChannel));
82 
83 	if (peerChannel)
84 	{
85 		peerChannel->index = index;
86 		peerChannel->client = client;
87 		peerChannel->channelFlags = flags;
88 		peerChannel->channelId = mcsChannel->ChannelId;
89 		peerChannel->mcsChannel = mcsChannel;
90 		mcsChannel->handle = (void*)peerChannel;
91 	}
92 
93 	return (HANDLE)peerChannel;
94 }
95 
freerdp_peer_virtual_channel_close(freerdp_peer * client,HANDLE hChannel)96 static BOOL freerdp_peer_virtual_channel_close(freerdp_peer* client, HANDLE hChannel)
97 {
98 	rdpMcsChannel* mcsChannel = NULL;
99 	rdpPeerChannel* peerChannel = NULL;
100 
101 	if (!hChannel)
102 		return FALSE;
103 
104 	peerChannel = (rdpPeerChannel*)hChannel;
105 	mcsChannel = peerChannel->mcsChannel;
106 	mcsChannel->handle = NULL;
107 	free(peerChannel);
108 	return TRUE;
109 }
110 
freerdp_peer_virtual_channel_write(freerdp_peer * client,HANDLE hChannel,const BYTE * buffer,UINT32 length)111 static int freerdp_peer_virtual_channel_write(freerdp_peer* client, HANDLE hChannel,
112                                               const BYTE* buffer, UINT32 length)
113 {
114 	wStream* s;
115 	UINT32 flags;
116 	UINT32 chunkSize;
117 	UINT32 maxChunkSize;
118 	UINT32 totalLength;
119 	rdpPeerChannel* peerChannel;
120 	rdpMcsChannel* mcsChannel;
121 	rdpRdp* rdp = client->context->rdp;
122 
123 	if (!hChannel)
124 		return -1;
125 
126 	peerChannel = (rdpPeerChannel*)hChannel;
127 	mcsChannel = peerChannel->mcsChannel;
128 
129 	if (peerChannel->channelFlags & WTS_CHANNEL_OPTION_DYNAMIC)
130 		return -1; /* not yet supported */
131 
132 	maxChunkSize = rdp->settings->VirtualChannelChunkSize;
133 	totalLength = length;
134 	flags = CHANNEL_FLAG_FIRST;
135 
136 	while (length > 0)
137 	{
138 		s = rdp_send_stream_init(rdp);
139 
140 		if (!s)
141 			return -1;
142 
143 		if (length > maxChunkSize)
144 		{
145 			chunkSize = rdp->settings->VirtualChannelChunkSize;
146 		}
147 		else
148 		{
149 			chunkSize = length;
150 			flags |= CHANNEL_FLAG_LAST;
151 		}
152 
153 		if (mcsChannel->options & CHANNEL_OPTION_SHOW_PROTOCOL)
154 			flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
155 
156 		Stream_Write_UINT32(s, totalLength);
157 		Stream_Write_UINT32(s, flags);
158 
159 		if (!Stream_EnsureRemainingCapacity(s, chunkSize))
160 		{
161 			Stream_Release(s);
162 			return -1;
163 		}
164 
165 		Stream_Write(s, buffer, chunkSize);
166 
167 		if (!rdp_send(rdp, s, peerChannel->channelId))
168 			return -1;
169 
170 		buffer += chunkSize;
171 		length -= chunkSize;
172 		flags = 0;
173 	}
174 
175 	return 1;
176 }
177 
freerdp_peer_virtual_channel_get_data(freerdp_peer * client,HANDLE hChannel)178 static void* freerdp_peer_virtual_channel_get_data(freerdp_peer* client, HANDLE hChannel)
179 {
180 	rdpPeerChannel* peerChannel = (rdpPeerChannel*)hChannel;
181 
182 	if (!hChannel)
183 		return NULL;
184 
185 	return peerChannel->extra;
186 }
187 
freerdp_peer_virtual_channel_set_data(freerdp_peer * client,HANDLE hChannel,void * data)188 static int freerdp_peer_virtual_channel_set_data(freerdp_peer* client, HANDLE hChannel, void* data)
189 {
190 	rdpPeerChannel* peerChannel = (rdpPeerChannel*)hChannel;
191 
192 	if (!hChannel)
193 		return -1;
194 
195 	peerChannel->extra = data;
196 	return 1;
197 }
198 
freerdp_peer_initialize(freerdp_peer * client)199 static BOOL freerdp_peer_initialize(freerdp_peer* client)
200 {
201 	rdpRdp* rdp = client->context->rdp;
202 	rdpSettings* settings = rdp->settings;
203 	settings->ServerMode = TRUE;
204 	settings->FrameAcknowledge = 0;
205 	settings->LocalConnection = client->local;
206 	rdp->state = CONNECTION_STATE_INITIAL;
207 
208 	if (settings->RdpKeyFile)
209 	{
210 		settings->RdpServerRsaKey = key_new(settings->RdpKeyFile);
211 
212 		if (!settings->RdpServerRsaKey)
213 		{
214 			WLog_ERR(TAG, "invalid RDP key file %s", settings->RdpKeyFile);
215 			return FALSE;
216 		}
217 	}
218 	else if (settings->RdpKeyContent)
219 	{
220 		settings->RdpServerRsaKey = key_new_from_content(settings->RdpKeyContent, NULL);
221 
222 		if (!settings->RdpServerRsaKey)
223 		{
224 			WLog_ERR(TAG, "invalid RDP key content");
225 			return FALSE;
226 		}
227 	}
228 
229 	return TRUE;
230 }
231 
freerdp_peer_get_fds(freerdp_peer * client,void ** rfds,int * rcount)232 static BOOL freerdp_peer_get_fds(freerdp_peer* client, void** rfds, int* rcount)
233 {
234 	rdpTransport* transport = client->context->rdp->transport;
235 	transport_get_fds(transport, rfds, rcount);
236 	return TRUE;
237 }
238 
freerdp_peer_get_event_handle(freerdp_peer * client)239 static HANDLE freerdp_peer_get_event_handle(freerdp_peer* client)
240 {
241 	HANDLE hEvent = NULL;
242 	rdpTransport* transport = client->context->rdp->transport;
243 	BIO_get_event(transport->frontBio, &hEvent);
244 	return hEvent;
245 }
246 
freerdp_peer_get_event_handles(freerdp_peer * client,HANDLE * events,DWORD count)247 static DWORD freerdp_peer_get_event_handles(freerdp_peer* client, HANDLE* events, DWORD count)
248 {
249 	return transport_get_event_handles(client->context->rdp->transport, events, count);
250 }
251 
freerdp_peer_check_fds(freerdp_peer * peer)252 static BOOL freerdp_peer_check_fds(freerdp_peer* peer)
253 {
254 	int status;
255 	rdpRdp* rdp;
256 	rdp = peer->context->rdp;
257 	status = rdp_check_fds(rdp);
258 
259 	if (status < 0)
260 		return FALSE;
261 
262 	return TRUE;
263 }
264 
peer_recv_data_pdu(freerdp_peer * client,wStream * s,UINT16 totalLength)265 static BOOL peer_recv_data_pdu(freerdp_peer* client, wStream* s, UINT16 totalLength)
266 {
267 	BYTE type;
268 	UINT16 length;
269 	UINT32 share_id;
270 	BYTE compressed_type;
271 	UINT16 compressed_len;
272 
273 	if (!rdp_read_share_data_header(s, &length, &type, &share_id, &compressed_type,
274 	                                &compressed_len))
275 		return FALSE;
276 
277 #ifdef WITH_DEBUG_RDP
278 	WLog_DBG(TAG, "recv %s Data PDU (0x%02" PRIX8 "), length: %" PRIu16 "",
279 	         data_pdu_type_to_string(type), type, length);
280 #endif
281 
282 	switch (type)
283 	{
284 		case DATA_PDU_TYPE_SYNCHRONIZE:
285 			if (!rdp_recv_client_synchronize_pdu(client->context->rdp, s))
286 				return FALSE;
287 
288 			break;
289 
290 		case DATA_PDU_TYPE_CONTROL:
291 			if (!rdp_server_accept_client_control_pdu(client->context->rdp, s))
292 				return FALSE;
293 
294 			break;
295 
296 		case DATA_PDU_TYPE_INPUT:
297 			if (!input_recv(client->context->rdp->input, s))
298 				return FALSE;
299 
300 			break;
301 
302 		case DATA_PDU_TYPE_BITMAP_CACHE_PERSISTENT_LIST:
303 			if (!rdp_server_accept_client_persistent_key_list_pdu(client->context->rdp, s))
304 				return FALSE;
305 			break;
306 
307 		case DATA_PDU_TYPE_FONT_LIST:
308 			if (!rdp_server_accept_client_font_list_pdu(client->context->rdp, s))
309 				return FALSE;
310 
311 			break;
312 
313 		case DATA_PDU_TYPE_SHUTDOWN_REQUEST:
314 			mcs_send_disconnect_provider_ultimatum(client->context->rdp->mcs);
315 			return FALSE;
316 
317 		case DATA_PDU_TYPE_FRAME_ACKNOWLEDGE:
318 			if (Stream_GetRemainingLength(s) < 4)
319 				return FALSE;
320 
321 			Stream_Read_UINT32(s, client->ack_frame_id);
322 			IFCALL(client->update->SurfaceFrameAcknowledge, client->update->context,
323 			       client->ack_frame_id);
324 			break;
325 
326 		case DATA_PDU_TYPE_REFRESH_RECT:
327 			if (!update_read_refresh_rect(client->update, s))
328 				return FALSE;
329 
330 			break;
331 
332 		case DATA_PDU_TYPE_SUPPRESS_OUTPUT:
333 			if (!update_read_suppress_output(client->update, s))
334 				return FALSE;
335 
336 			break;
337 
338 		default:
339 			WLog_ERR(TAG, "Data PDU type %" PRIu8 "", type);
340 			break;
341 	}
342 
343 	return TRUE;
344 }
345 
peer_recv_tpkt_pdu(freerdp_peer * client,wStream * s)346 static int peer_recv_tpkt_pdu(freerdp_peer* client, wStream* s)
347 {
348 	rdpRdp* rdp;
349 	UINT16 length;
350 	UINT16 pduType;
351 	UINT16 pduSource;
352 	UINT16 channelId;
353 	UINT16 securityFlags = 0;
354 	rdp = client->context->rdp;
355 
356 	if (!rdp_read_header(rdp, s, &length, &channelId))
357 	{
358 		WLog_ERR(TAG, "Incorrect RDP header.");
359 		return -1;
360 	}
361 
362 	rdp->inPackets++;
363 	if (freerdp_shall_disconnect(rdp->instance))
364 		return 0;
365 
366 	if (rdp->settings->UseRdpSecurityLayer)
367 	{
368 		if (!rdp_read_security_header(s, &securityFlags, &length))
369 			return -1;
370 
371 		if (securityFlags & SEC_ENCRYPT)
372 		{
373 			if (!rdp_decrypt(rdp, s, &length, securityFlags))
374 			{
375 				WLog_ERR(TAG, "rdp_decrypt failed");
376 				return -1;
377 			}
378 		}
379 	}
380 
381 	if (channelId == MCS_GLOBAL_CHANNEL_ID)
382 	{
383 		UINT16 pduLength, remain;
384 		if (!rdp_read_share_control_header(s, &pduLength, &remain, &pduType, &pduSource))
385 			return -1;
386 
387 		client->settings->PduSource = pduSource;
388 
389 		WLog_DBG(TAG, "Received %s", pdu_type_to_str(pduType));
390 		switch (pduType)
391 		{
392 			case PDU_TYPE_DATA:
393 				if (!peer_recv_data_pdu(client, s, pduLength))
394 					return -1;
395 
396 				break;
397 
398 			case PDU_TYPE_CONFIRM_ACTIVE:
399 				if (!rdp_server_accept_confirm_active(rdp, s, pduLength))
400 					return -1;
401 
402 				break;
403 
404 			case PDU_TYPE_FLOW_RESPONSE:
405 			case PDU_TYPE_FLOW_STOP:
406 			case PDU_TYPE_FLOW_TEST:
407 				if (!Stream_SafeSeek(s, remain))
408 					return -1;
409 				break;
410 
411 			default:
412 				WLog_ERR(TAG, "Client sent pduType %" PRIu16 "", pduType);
413 				return -1;
414 		}
415 	}
416 	else if ((rdp->mcs->messageChannelId > 0) && (channelId == rdp->mcs->messageChannelId))
417 	{
418 		if (!rdp->settings->UseRdpSecurityLayer)
419 			if (!rdp_read_security_header(s, &securityFlags, NULL))
420 				return -1;
421 
422 		return rdp_recv_message_channel_pdu(rdp, s, securityFlags);
423 	}
424 	else
425 	{
426 		if (!freerdp_channel_peer_process(client, s, channelId))
427 			return -1;
428 	}
429 	if (!tpkt_ensure_stream_consumed(s, length))
430 		return -1;
431 
432 	return 0;
433 }
434 
peer_recv_fastpath_pdu(freerdp_peer * client,wStream * s)435 static int peer_recv_fastpath_pdu(freerdp_peer* client, wStream* s)
436 {
437 	rdpRdp* rdp;
438 	UINT16 length;
439 	rdpFastPath* fastpath;
440 	rdp = client->context->rdp;
441 	fastpath = rdp->fastpath;
442 	fastpath_read_header_rdp(fastpath, s, &length);
443 
444 	if ((length == 0) || (length > Stream_GetRemainingLength(s)))
445 	{
446 		WLog_ERR(TAG, "incorrect FastPath PDU header length %" PRIu16 "", length);
447 		return -1;
448 	}
449 
450 	if (fastpath->encryptionFlags & FASTPATH_OUTPUT_ENCRYPTED)
451 	{
452 		if (!rdp_decrypt(rdp, s, &length,
453 		                 (fastpath->encryptionFlags & FASTPATH_OUTPUT_SECURE_CHECKSUM)
454 		                     ? SEC_SECURE_CHECKSUM
455 		                     : 0))
456 			return -1;
457 	}
458 
459 	rdp->inPackets++;
460 
461 	return fastpath_recv_inputs(fastpath, s);
462 }
463 
peer_recv_pdu(freerdp_peer * client,wStream * s)464 static int peer_recv_pdu(freerdp_peer* client, wStream* s)
465 {
466 	if (tpkt_verify_header(s))
467 		return peer_recv_tpkt_pdu(client, s);
468 	else
469 		return peer_recv_fastpath_pdu(client, s);
470 }
471 
peer_recv_callback(rdpTransport * transport,wStream * s,void * extra)472 static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra)
473 {
474 	UINT32 SelectedProtocol;
475 	freerdp_peer* client = (freerdp_peer*)extra;
476 	rdpRdp* rdp = client->context->rdp;
477 
478 	switch (rdp->state)
479 	{
480 		case CONNECTION_STATE_INITIAL:
481 			if (!rdp_server_accept_nego(rdp, s))
482 			{
483 				WLog_ERR(TAG, "%s: %s - rdp_server_accept_nego() fail", __FUNCTION__,
484 				         rdp_server_connection_state_string(rdp->state));
485 				return -1;
486 			}
487 
488 			SelectedProtocol = nego_get_selected_protocol(rdp->nego);
489 			client->settings->NlaSecurity = (SelectedProtocol & PROTOCOL_HYBRID) ? TRUE : FALSE;
490 			client->settings->TlsSecurity = (SelectedProtocol & PROTOCOL_SSL) ? TRUE : FALSE;
491 			client->settings->RdpSecurity = (SelectedProtocol == PROTOCOL_RDP) ? TRUE : FALSE;
492 
493 			if (SelectedProtocol & PROTOCOL_HYBRID)
494 			{
495 				SEC_WINNT_AUTH_IDENTITY* identity = nego_get_identity(rdp->nego);
496 				sspi_CopyAuthIdentity(&client->identity, identity);
497 				IFCALLRET(client->Logon, client->authenticated, client, &client->identity, TRUE);
498 				nego_free_nla(rdp->nego);
499 			}
500 			else
501 			{
502 				IFCALLRET(client->Logon, client->authenticated, client, &client->identity, FALSE);
503 			}
504 
505 			break;
506 
507 		case CONNECTION_STATE_NEGO:
508 			if (!rdp_server_accept_mcs_connect_initial(rdp, s))
509 			{
510 				WLog_ERR(TAG,
511 				         "%s: %s - "
512 				         "rdp_server_accept_mcs_connect_initial() fail",
513 				         __FUNCTION__, rdp_server_connection_state_string(rdp->state));
514 				return -1;
515 			}
516 
517 			break;
518 
519 		case CONNECTION_STATE_MCS_CONNECT:
520 			if (!rdp_server_accept_mcs_erect_domain_request(rdp, s))
521 			{
522 				WLog_ERR(TAG,
523 				         "%s: %s - "
524 				         "rdp_server_accept_mcs_erect_domain_request() fail",
525 				         __FUNCTION__, rdp_server_connection_state_string(rdp->state));
526 				return -1;
527 			}
528 
529 			break;
530 
531 		case CONNECTION_STATE_MCS_ERECT_DOMAIN:
532 			if (!rdp_server_accept_mcs_attach_user_request(rdp, s))
533 			{
534 				WLog_ERR(TAG,
535 				         "%s: %s - "
536 				         "rdp_server_accept_mcs_attach_user_request() fail",
537 				         __FUNCTION__, rdp_server_connection_state_string(rdp->state));
538 				return -1;
539 			}
540 
541 			break;
542 
543 		case CONNECTION_STATE_MCS_ATTACH_USER:
544 			if (!rdp_server_accept_mcs_channel_join_request(rdp, s))
545 			{
546 				WLog_ERR(TAG,
547 				         "%s: %s - "
548 				         "rdp_server_accept_mcs_channel_join_request() fail",
549 				         __FUNCTION__, rdp_server_connection_state_string(rdp->state));
550 				return -1;
551 			}
552 
553 			break;
554 
555 		case CONNECTION_STATE_RDP_SECURITY_COMMENCEMENT:
556 			if (rdp->settings->UseRdpSecurityLayer)
557 			{
558 				if (!rdp_server_establish_keys(rdp, s))
559 				{
560 					WLog_ERR(TAG,
561 					         "%s: %s - "
562 					         "rdp_server_establish_keys() fail",
563 					         __FUNCTION__, rdp_server_connection_state_string(rdp->state));
564 					return -1;
565 				}
566 			}
567 
568 			rdp_server_transition_to_state(rdp, CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE);
569 
570 			if (Stream_GetRemainingLength(s) > 0)
571 				return peer_recv_callback(transport, s, extra);
572 
573 			break;
574 
575 		case CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE:
576 			if (!rdp_recv_client_info(rdp, s))
577 			{
578 				WLog_ERR(TAG,
579 				         "%s: %s - "
580 				         "rdp_recv_client_info() fail",
581 				         __FUNCTION__, rdp_server_connection_state_string(rdp->state));
582 				return -1;
583 			}
584 
585 			rdp_server_transition_to_state(rdp, CONNECTION_STATE_LICENSING);
586 			return peer_recv_callback(transport, NULL, extra);
587 
588 		case CONNECTION_STATE_LICENSING:
589 		{
590 			LicenseCallbackResult res;
591 
592 			if (!client->LicenseCallback)
593 			{
594 				WLog_ERR(TAG,
595 				         "%s: LicenseCallback has been removed, assuming "
596 				         "licensing is ok (please fix your app)",
597 				         __FUNCTION__);
598 				res = LICENSE_CB_COMPLETED;
599 			}
600 			else
601 				res = client->LicenseCallback(client, s);
602 
603 			switch (res)
604 			{
605 				case LICENSE_CB_INTERNAL_ERROR:
606 					WLog_ERR(TAG,
607 					         "%s: %s - callback internal "
608 					         "error, aborting",
609 					         __FUNCTION__, rdp_server_connection_state_string(rdp->state));
610 					return -1;
611 
612 				case LICENSE_CB_ABORT:
613 					return -1;
614 
615 				case LICENSE_CB_IN_PROGRESS:
616 					break;
617 
618 				case LICENSE_CB_COMPLETED:
619 					rdp_server_transition_to_state(rdp, CONNECTION_STATE_CAPABILITIES_EXCHANGE);
620 					return peer_recv_callback(transport, NULL, extra);
621 
622 				default:
623 					WLog_ERR(TAG,
624 					         "%s: CONNECTION_STATE_LICENSING - unknown license callback "
625 					         "result %d",
626 					         __FUNCTION__, res);
627 					break;
628 			}
629 
630 			break;
631 		}
632 
633 		case CONNECTION_STATE_CAPABILITIES_EXCHANGE:
634 			if (!rdp->AwaitCapabilities)
635 			{
636 				if (client->Capabilities && !client->Capabilities(client))
637 					return -1;
638 
639 				if (!rdp_send_demand_active(rdp))
640 				{
641 					WLog_ERR(TAG,
642 					         "%s: %s - "
643 					         "rdp_send_demand_active() fail",
644 					         __FUNCTION__, rdp_server_connection_state_string(rdp->state));
645 					return -1;
646 				}
647 
648 				rdp->AwaitCapabilities = TRUE;
649 
650 				if (s)
651 				{
652 					if (peer_recv_pdu(client, s) < 0)
653 					{
654 						WLog_ERR(TAG,
655 						         "%s: %s - "
656 						         "peer_recv_pdu() fail",
657 						         __FUNCTION__, rdp_server_connection_state_string(rdp->state));
658 						return -1;
659 					}
660 				}
661 			}
662 			else
663 			{
664 				/**
665 				 * During reactivation sequence the client might sent some input or channel data
666 				 * before receiving the Deactivate All PDU. We need to process them as usual.
667 				 */
668 				if (peer_recv_pdu(client, s) < 0)
669 				{
670 					WLog_ERR(TAG,
671 					         "%s: %s - "
672 					         "peer_recv_pdu() fail",
673 					         __FUNCTION__, rdp_server_connection_state_string(rdp->state));
674 					return -1;
675 				}
676 			}
677 
678 			break;
679 
680 		case CONNECTION_STATE_FINALIZATION:
681 			if (peer_recv_pdu(client, s) < 0)
682 			{
683 				WLog_ERR(TAG, "%s: %s - peer_recv_pdu() fail", __FUNCTION__,
684 				         rdp_server_connection_state_string(rdp->state));
685 				return -1;
686 			}
687 
688 			break;
689 
690 		case CONNECTION_STATE_ACTIVE:
691 			if (peer_recv_pdu(client, s) < 0)
692 			{
693 				WLog_ERR(TAG, "%s: %s - peer_recv_pdu() fail", __FUNCTION__,
694 				         rdp_server_connection_state_string(rdp->state));
695 				return -1;
696 			}
697 
698 			break;
699 
700 		default:
701 			WLog_ERR(TAG, "%s state %d", rdp_server_connection_state_string(rdp->state),
702 			         rdp->state);
703 			return -1;
704 	}
705 
706 	return 0;
707 }
708 
freerdp_peer_close(freerdp_peer * client)709 static BOOL freerdp_peer_close(freerdp_peer* client)
710 {
711 	UINT32 SelectedProtocol;
712 	/** if negotiation has failed, we're not MCS connected. So don't
713 	 * 	send anything else, or some mstsc will consider that as an error
714 	 */
715 	SelectedProtocol = nego_get_selected_protocol(client->context->rdp->nego);
716 
717 	if (SelectedProtocol & PROTOCOL_FAILED_NEGO)
718 		return TRUE;
719 
720 	/**
721 	 * [MS-RDPBCGR] 1.3.1.4.2 User-Initiated Disconnection Sequence on Server
722 	 * The server first sends the client a Deactivate All PDU followed by an
723 	 * optional MCS Disconnect Provider Ultimatum PDU.
724 	 */
725 	if (!rdp_send_deactivate_all(client->context->rdp))
726 		return FALSE;
727 
728 	if (freerdp_settings_get_bool(client->settings, FreeRDP_SupportErrorInfoPdu))
729 	{
730 		rdp_send_error_info(client->context->rdp);
731 	}
732 
733 	return mcs_send_disconnect_provider_ultimatum(client->context->rdp->mcs);
734 }
735 
freerdp_peer_disconnect(freerdp_peer * client)736 static void freerdp_peer_disconnect(freerdp_peer* client)
737 {
738 	rdpTransport* transport = client->context->rdp->transport;
739 	transport_disconnect(transport);
740 }
741 
freerdp_peer_send_channel_data(freerdp_peer * client,UINT16 channelId,const BYTE * data,size_t size)742 static BOOL freerdp_peer_send_channel_data(freerdp_peer* client, UINT16 channelId, const BYTE* data,
743                                            size_t size)
744 {
745 	return rdp_send_channel_data(client->context->rdp, channelId, data, size);
746 }
747 
freerdp_peer_is_write_blocked(freerdp_peer * peer)748 static BOOL freerdp_peer_is_write_blocked(freerdp_peer* peer)
749 {
750 	rdpTransport* transport = peer->context->rdp->transport;
751 	return transport_is_write_blocked(transport);
752 }
753 
freerdp_peer_drain_output_buffer(freerdp_peer * peer)754 static int freerdp_peer_drain_output_buffer(freerdp_peer* peer)
755 {
756 	rdpTransport* transport = peer->context->rdp->transport;
757 	return transport_drain_output_buffer(transport);
758 }
759 
freerdp_peer_has_more_to_read(freerdp_peer * peer)760 static BOOL freerdp_peer_has_more_to_read(freerdp_peer* peer)
761 {
762 	return peer->context->rdp->transport->haveMoreBytesToRead;
763 }
764 
freerdp_peer_nolicense(freerdp_peer * peer,wStream * s)765 static LicenseCallbackResult freerdp_peer_nolicense(freerdp_peer* peer, wStream* s)
766 {
767 	rdpRdp* rdp = peer->context->rdp;
768 
769 	if (!license_send_valid_client_error_packet(rdp))
770 	{
771 		WLog_ERR(TAG, "freerdp_peer_nolicense: license_send_valid_client_error_packet() failed");
772 		return LICENSE_CB_ABORT;
773 	}
774 
775 	return LICENSE_CB_COMPLETED;
776 }
777 
freerdp_peer_context_new(freerdp_peer * client)778 BOOL freerdp_peer_context_new(freerdp_peer* client)
779 {
780 	rdpRdp* rdp;
781 	rdpContext* context;
782 	BOOL ret = TRUE;
783 
784 	if (!client)
785 		return FALSE;
786 
787 	if (!(context = (rdpContext*)calloc(1, client->ContextSize)))
788 		goto fail_context;
789 
790 	client->context = context;
791 	context->peer = client;
792 	context->ServerMode = TRUE;
793 	context->settings = client->settings;
794 
795 	if (!(context->metrics = metrics_new(context)))
796 		goto fail_metrics;
797 
798 	if (!(rdp = rdp_new(context)))
799 		goto fail_rdp;
800 
801 	client->input = rdp->input;
802 	client->update = rdp->update;
803 	client->settings = rdp->settings;
804 	client->autodetect = rdp->autodetect;
805 	context->rdp = rdp;
806 	context->input = client->input;
807 	context->update = client->update;
808 	context->settings = client->settings;
809 	context->autodetect = client->autodetect;
810 	client->update->context = context;
811 	client->input->context = context;
812 	client->autodetect->context = context;
813 	update_register_server_callbacks(client->update);
814 	autodetect_register_server_callbacks(client->autodetect);
815 
816 	if (!(context->errorDescription = calloc(1, 500)))
817 	{
818 		WLog_ERR(TAG, "calloc failed!");
819 		goto fail_error_description;
820 	}
821 
822 	if (!transport_attach(rdp->transport, client->sockfd))
823 		goto fail_transport_attach;
824 
825 	rdp->transport->ReceiveCallback = peer_recv_callback;
826 	rdp->transport->ReceiveExtra = client;
827 	transport_set_blocking_mode(rdp->transport, FALSE);
828 	client->IsWriteBlocked = freerdp_peer_is_write_blocked;
829 	client->DrainOutputBuffer = freerdp_peer_drain_output_buffer;
830 	client->HasMoreToRead = freerdp_peer_has_more_to_read;
831 	client->LicenseCallback = freerdp_peer_nolicense;
832 	IFCALLRET(client->ContextNew, ret, client, client->context);
833 
834 	if (ret)
835 		return TRUE;
836 
837 	WLog_ERR(TAG, "ContextNew callback failed");
838 fail_transport_attach:
839 	free(context->errorDescription);
840 fail_error_description:
841 	rdp_free(client->context->rdp);
842 fail_rdp:
843 	metrics_free(context->metrics);
844 fail_metrics:
845 	free(client->context);
846 fail_context:
847 	client->context = NULL;
848 	WLog_ERR(TAG, "Failed to create new peer context");
849 	return FALSE;
850 }
851 
freerdp_peer_context_free(freerdp_peer * client)852 void freerdp_peer_context_free(freerdp_peer* client)
853 {
854 	IFCALL(client->ContextFree, client, client->context);
855 
856 	if (client->context)
857 	{
858 		free(client->context->errorDescription);
859 		client->context->errorDescription = NULL;
860 		rdp_free(client->context->rdp);
861 		client->context->rdp = NULL;
862 		metrics_free(client->context->metrics);
863 		client->context->metrics = NULL;
864 		free(client->context);
865 		client->context = NULL;
866 	}
867 }
868 
freerdp_peer_new(int sockfd)869 freerdp_peer* freerdp_peer_new(int sockfd)
870 {
871 	UINT32 option_value;
872 	socklen_t option_len;
873 	freerdp_peer* client;
874 	client = (freerdp_peer*)calloc(1, sizeof(freerdp_peer));
875 
876 	if (!client)
877 		return NULL;
878 
879 	option_value = TRUE;
880 	option_len = sizeof(option_value);
881 	setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (void*)&option_value, option_len);
882 
883 	if (client)
884 	{
885 		client->sockfd = sockfd;
886 		client->ContextSize = sizeof(rdpContext);
887 		client->Initialize = freerdp_peer_initialize;
888 		client->GetFileDescriptor = freerdp_peer_get_fds;
889 		client->GetEventHandle = freerdp_peer_get_event_handle;
890 		client->GetEventHandles = freerdp_peer_get_event_handles;
891 		client->CheckFileDescriptor = freerdp_peer_check_fds;
892 		client->Close = freerdp_peer_close;
893 		client->Disconnect = freerdp_peer_disconnect;
894 		client->SendChannelData = freerdp_peer_send_channel_data;
895 		client->IsWriteBlocked = freerdp_peer_is_write_blocked;
896 		client->DrainOutputBuffer = freerdp_peer_drain_output_buffer;
897 		client->HasMoreToRead = freerdp_peer_has_more_to_read;
898 		client->VirtualChannelOpen = freerdp_peer_virtual_channel_open;
899 		client->VirtualChannelClose = freerdp_peer_virtual_channel_close;
900 		client->VirtualChannelWrite = freerdp_peer_virtual_channel_write;
901 		client->VirtualChannelRead = NULL; /* must be defined by server application */
902 		client->VirtualChannelGetData = freerdp_peer_virtual_channel_get_data;
903 		client->VirtualChannelSetData = freerdp_peer_virtual_channel_set_data;
904 	}
905 
906 	return client;
907 }
908 
freerdp_peer_free(freerdp_peer * client)909 void freerdp_peer_free(freerdp_peer* client)
910 {
911 	if (!client)
912 		return;
913 
914 	free(client);
915 }
916