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