2
* FreeRDP: A Remote Desktop Protocol Implementation
5
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
7
* Licensed under the Apache License, Version 2.0 (the "License");
8
* you may not use this file except in compliance with the License.
9
* You may obtain a copy of the License at
11
* http://www.apache.org/licenses/LICENSE-2.0
13
* Unless required by applicable law or agreed to in writing, software
14
* distributed under the License is distributed on an "AS IS" BASIS,
15
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
* See the License for the specific language governing permissions and
17
* limitations under the License.
24
#include <winpr/crt.h>
29
#include "redirection.h"
31
#include <freerdp/crypto/per.h>
34
static const char* const DATA_PDU_TYPE_STRINGS[] =
36
"?", "?", /* 0x00 - 0x01 */
38
"?", "?", "?", "?", "?", "?", "?", "?", /* 0x03 - 0x0A */
39
"?", "?", "?", "?", "?", "?", "?", "?", "?", /* 0x0B - 0x13 */
41
"?", "?", "?", "?", "?", "?", /* 0x15 - 0x1A */
44
"?", "?", /* 0x1D - 0x1E */
45
"Synchronize", /* 0x1F */
47
"Refresh Rect", /* 0x21 */
48
"Play Sound", /* 0x22 */
49
"Suppress Output", /* 0x23 */
50
"Shutdown Request", /* 0x24 */
51
"Shutdown Denied", /* 0x25 */
52
"Save Session Info", /* 0x26 */
53
"Font List", /* 0x27 */
54
"Font Map", /* 0x28 */
55
"Set Keyboard Indicators", /* 0x29 */
57
"Bitmap Cache Persistent List", /* 0x2B */
58
"Bitmap Cache Error", /* 0x2C */
59
"Set Keyboard IME Status", /* 0x2D */
60
"Offscreen Cache Error", /* 0x2E */
61
"Set Error Info", /* 0x2F */
62
"Draw Nine Grid Error", /* 0x30 */
63
"Draw GDI+ Error", /* 0x31 */
64
"ARC Status", /* 0x32 */
65
"?", "?", "?", /* 0x33 - 0x35 */
66
"Status Info", /* 0x36 */
67
"Monitor Layout" /* 0x37 */
68
"?", "?", "?", /* 0x38 - 0x40 */
69
"?", "?", "?", "?", "?", "?" /* 0x41 - 0x46 */
74
* Read RDP Security Header.\n
77
* @param flags security flags
80
BOOL rdp_read_security_header(wStream* s, UINT16* flags)
82
/* Basic Security Header */
83
if (Stream_GetRemainingLength(s) < 4)
85
Stream_Read_UINT16(s, *flags); /* flags */
86
Stream_Seek(s, 2); /* flagsHi (unused) */
91
* Write RDP Security Header.\n
94
* @param flags security flags
97
void rdp_write_security_header(wStream* s, UINT16 flags)
99
/* Basic Security Header */
100
Stream_Write_UINT16(s, flags); /* flags */
101
Stream_Write_UINT16(s, 0); /* flagsHi (unused) */
104
BOOL rdp_read_share_control_header(wStream* s, UINT16* length, UINT16* type, UINT16* channel_id)
106
if (Stream_GetRemainingLength(s) < 2)
109
/* Share Control Header */
110
Stream_Read_UINT16(s, *length); /* totalLength */
112
if (*length - 2 > Stream_GetRemainingLength(s))
115
Stream_Read_UINT16(s, *type); /* pduType */
116
*type &= 0x0F; /* type is in the 4 least significant bits */
119
Stream_Read_UINT16(s, *channel_id); /* pduSource */
121
*channel_id = 0; /* Windows XP can send such short DEACTIVATE_ALL PDUs. */
126
void rdp_write_share_control_header(wStream* s, UINT16 length, UINT16 type, UINT16 channel_id)
128
length -= RDP_PACKET_HEADER_MAX_LENGTH;
130
/* Share Control Header */
131
Stream_Write_UINT16(s, length); /* totalLength */
132
Stream_Write_UINT16(s, type | 0x10); /* pduType */
133
Stream_Write_UINT16(s, channel_id); /* pduSource */
136
BOOL rdp_read_share_data_header(wStream* s, UINT16* length, BYTE* type, UINT32* share_id,
137
BYTE *compressed_type, UINT16 *compressed_len)
139
if (Stream_GetRemainingLength(s) < 12)
142
/* Share Data Header */
143
Stream_Read_UINT32(s, *share_id); /* shareId (4 bytes) */
144
Stream_Seek_UINT8(s); /* pad1 (1 byte) */
145
Stream_Seek_UINT8(s); /* streamId (1 byte) */
146
Stream_Read_UINT16(s, *length); /* uncompressedLength (2 bytes) */
147
Stream_Read_UINT8(s, *type); /* pduType2, Data PDU Type (1 byte) */
148
Stream_Read_UINT8(s, *compressed_type); /* compressedType (1 byte) */
149
Stream_Read_UINT16(s, *compressed_len); /* compressedLength (2 bytes) */
153
void rdp_write_share_data_header(wStream* s, UINT16 length, BYTE type, UINT32 share_id)
155
length -= RDP_PACKET_HEADER_MAX_LENGTH;
156
length -= RDP_SHARE_CONTROL_HEADER_LENGTH;
157
length -= RDP_SHARE_DATA_HEADER_LENGTH;
159
/* Share Data Header */
160
Stream_Write_UINT32(s, share_id); /* shareId (4 bytes) */
161
Stream_Write_UINT8(s, 0); /* pad1 (1 byte) */
162
Stream_Write_UINT8(s, STREAM_LOW); /* streamId (1 byte) */
163
Stream_Write_UINT16(s, length); /* uncompressedLength (2 bytes) */
164
Stream_Write_UINT8(s, type); /* pduType2, Data PDU Type (1 byte) */
165
Stream_Write_UINT8(s, 0); /* compressedType (1 byte) */
166
Stream_Write_UINT16(s, 0); /* compressedLength (2 bytes) */
169
static int rdp_security_stream_init(rdpRdp* rdp, wStream* s)
175
if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
178
rdp->sec_flags |= SEC_ENCRYPT;
180
if (rdp->do_secure_checksum)
181
rdp->sec_flags |= SEC_SECURE_CHECKSUM;
183
else if (rdp->sec_flags != 0)
191
int rdp_init_stream(rdpRdp* rdp, wStream* s)
193
Stream_Seek(s, RDP_PACKET_HEADER_MAX_LENGTH);
194
rdp_security_stream_init(rdp, s);
198
wStream* rdp_send_stream_init(rdpRdp* rdp)
201
s = transport_send_stream_init(rdp->transport, 2048);
202
rdp_init_stream(rdp, s);
206
int rdp_init_stream_pdu(rdpRdp* rdp, wStream* s)
208
Stream_Seek(s, RDP_PACKET_HEADER_MAX_LENGTH);
209
rdp_security_stream_init(rdp, s);
210
Stream_Seek(s, RDP_SHARE_CONTROL_HEADER_LENGTH);
214
int rdp_init_stream_data_pdu(rdpRdp* rdp, wStream* s)
216
Stream_Seek(s, RDP_PACKET_HEADER_MAX_LENGTH);
217
rdp_security_stream_init(rdp, s);
218
Stream_Seek(s, RDP_SHARE_CONTROL_HEADER_LENGTH);
219
Stream_Seek(s, RDP_SHARE_DATA_HEADER_LENGTH);
223
wStream* rdp_data_pdu_init(rdpRdp* rdp)
226
s = transport_send_stream_init(rdp->transport, 2048);
227
rdp_init_stream_data_pdu(rdp, s);
232
* Read an RDP packet header.\n
233
* @param rdp rdp module
235
* @param length RDP packet length
236
* @param channel_id channel id
239
BOOL rdp_read_header(rdpRdp* rdp, wStream* s, UINT16* length, UINT16* channel_id)
242
enum DomainMCSPDU MCSPDU;
244
MCSPDU = (rdp->settings->ServerMode) ? DomainMCSPDU_SendDataRequest : DomainMCSPDU_SendDataIndication;
246
if (!mcs_read_domain_mcspdu_header(s, &MCSPDU, length))
248
if (MCSPDU != DomainMCSPDU_DisconnectProviderUltimatum)
252
if (*length - 8 > Stream_GetRemainingLength(s))
255
if (MCSPDU == DomainMCSPDU_DisconnectProviderUltimatum)
258
TerminateEventArgs e;
259
rdpContext* context = rdp->instance->context;
261
(void) per_read_enumerated(s, &reason, 0);
262
DEBUG_RDP("DisconnectProviderUltimatum from server, reason code 0x%02x\n", reason);
264
rdp->disconnect = TRUE;
266
EventArgsInit(&e, "freerdp");
268
PubSub_OnTerminate(context->pubSub, context, &e);
273
if (Stream_GetRemainingLength(s) < 5)
276
per_read_integer16(s, &initiator, MCS_BASE_CHANNEL_ID); /* initiator (UserId) */
277
per_read_integer16(s, channel_id, 0); /* channelId */
278
Stream_Seek(s, 1); /* dataPriority + Segmentation (0x70) */
280
if (!per_read_length(s, length)) /* userData (OCTET_STRING) */
283
if (*length > Stream_GetRemainingLength(s))
290
* Write an RDP packet header.\n
291
* @param rdp rdp module
293
* @param length RDP packet length
294
* @param channel_id channel id
297
void rdp_write_header(rdpRdp* rdp, wStream* s, UINT16 length, UINT16 channel_id)
300
enum DomainMCSPDU MCSPDU;
302
MCSPDU = (rdp->settings->ServerMode) ? DomainMCSPDU_SendDataIndication : DomainMCSPDU_SendDataRequest;
304
if ((rdp->sec_flags & SEC_ENCRYPT) && (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS))
308
body_length = length - RDP_PACKET_HEADER_MAX_LENGTH - 16;
309
pad = 8 - (body_length % 8);
315
mcs_write_domain_mcspdu_header(s, MCSPDU, length, 0);
316
per_write_integer16(s, rdp->mcs->user_id, MCS_BASE_CHANNEL_ID); /* initiator */
317
per_write_integer16(s, channel_id, 0); /* channelId */
318
Stream_Write_UINT8(s, 0x70); /* dataPriority + segmentation */
320
* We always encode length in two bytes, eventhough we could use
321
* only one byte if length <= 0x7F. It is just easier that way,
322
* because we can leave room for fixed-length header, store all
323
* the data first and then store the header.
325
length = (length - RDP_PACKET_HEADER_MAX_LENGTH) | 0x8000;
326
Stream_Write_UINT16_BE(s, length); /* userData (OCTET_STRING) */
329
static UINT32 rdp_security_stream_out(rdpRdp* rdp, wStream* s, int length)
335
sec_flags = rdp->sec_flags;
339
rdp_write_security_header(s, sec_flags);
341
if (sec_flags & SEC_ENCRYPT)
343
if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
345
data = Stream_Pointer(s) + 12;
347
length = length - (data - Stream_Buffer(s));
348
Stream_Write_UINT16(s, 0x10); /* length */
349
Stream_Write_UINT8(s, 0x1); /* TSFIPS_VERSION 1*/
352
pad = 8 - (length % 8);
357
memset(data+length, 0, pad);
359
Stream_Write_UINT8(s, pad);
361
security_hmac_signature(data, length, Stream_Pointer(s), rdp);
363
security_fips_encrypt(data, length + pad, rdp);
367
data = Stream_Pointer(s) + 8;
368
length = length - (data - Stream_Buffer(s));
370
if (sec_flags & SEC_SECURE_CHECKSUM)
371
security_salted_mac_signature(rdp, data, length, TRUE, Stream_Pointer(s));
373
security_mac_signature(rdp, data, length, Stream_Pointer(s));
376
security_encrypt(Stream_Pointer(s), length, rdp);
386
static UINT32 rdp_get_sec_bytes(rdpRdp* rdp)
390
if (rdp->sec_flags & SEC_ENCRYPT)
394
if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
397
else if (rdp->sec_flags != 0)
410
* Send an RDP packet.\n
411
* @param rdp RDP module
413
* @param channel_id channel id
416
BOOL rdp_send(rdpRdp* rdp, wStream* s, UINT16 channel_id)
422
length = Stream_GetPosition(s);
423
Stream_SetPosition(s, 0);
425
rdp_write_header(rdp, s, length, channel_id);
427
sec_bytes = rdp_get_sec_bytes(rdp);
428
secm = Stream_GetPosition(s);
429
Stream_Seek(s, sec_bytes);
431
Stream_SetPosition(s, secm);
432
length += rdp_security_stream_out(rdp, s, length);
434
Stream_SetPosition(s, length);
435
Stream_SealLength(s);
437
if (transport_write(rdp->transport, s) < 0)
443
BOOL rdp_send_pdu(rdpRdp* rdp, wStream* s, UINT16 type, UINT16 channel_id)
449
length = Stream_GetPosition(s);
450
Stream_SetPosition(s, 0);
452
rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID);
454
sec_bytes = rdp_get_sec_bytes(rdp);
455
sec_hold = Stream_GetPosition(s);
456
Stream_Seek(s, sec_bytes);
458
rdp_write_share_control_header(s, length - sec_bytes, type, channel_id);
460
Stream_SetPosition(s, sec_hold);
461
length += rdp_security_stream_out(rdp, s, length);
463
Stream_SetPosition(s, length);
464
Stream_SealLength(s);
466
if (transport_write(rdp->transport, s) < 0)
472
BOOL rdp_send_data_pdu(rdpRdp* rdp, wStream* s, BYTE type, UINT16 channel_id)
478
length = Stream_GetPosition(s);
479
Stream_SetPosition(s, 0);
481
rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID);
483
sec_bytes = rdp_get_sec_bytes(rdp);
484
sec_hold = Stream_GetPosition(s);
485
Stream_Seek(s, sec_bytes);
487
rdp_write_share_control_header(s, length - sec_bytes, PDU_TYPE_DATA, channel_id);
488
rdp_write_share_data_header(s, length - sec_bytes, type, rdp->settings->ShareId);
490
Stream_SetPosition(s, sec_hold);
491
length += rdp_security_stream_out(rdp, s, length);
493
Stream_SetPosition(s, length);
494
Stream_SealLength(s);
496
if (transport_write(rdp->transport, s) < 0)
502
BOOL rdp_recv_set_error_info_data_pdu(rdpRdp* rdp, wStream* s)
504
if (Stream_GetRemainingLength(s) < 4)
507
Stream_Read_UINT32(s, rdp->errorInfo); /* errorInfo (4 bytes) */
509
if (rdp->errorInfo != ERRINFO_SUCCESS)
511
ErrorInfoEventArgs e;
512
rdpContext* context = rdp->instance->context;
514
rdp_print_errinfo(rdp->errorInfo);
516
EventArgsInit(&e, "freerdp");
517
e.code = rdp->errorInfo;
518
PubSub_OnErrorInfo(context->pubSub, context, &e);
524
int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s)
533
BYTE compressed_type;
534
UINT16 compressed_len;
536
if (!rdp_read_share_data_header(s, &length, &type, &share_id, &compressed_type, &compressed_len))
541
if (compressed_type & PACKET_COMPRESSED)
543
if (Stream_GetRemainingLength(s) < compressed_len - 18)
545
fprintf(stderr, "decompress_rdp: not enough bytes for compressed_len=%d\n", compressed_len);
549
if (decompress_rdp(rdp->mppc_dec, Stream_Pointer(s), compressed_len - 18, compressed_type, &roff, &rlen))
551
buffer = rdp->mppc_dec->history_buf + roff;
552
cs = StreamPool_Take(rdp->transport->ReceivePool, rlen);
554
Stream_SetPosition(cs, 0);
555
Stream_Write(cs, buffer, rlen);
556
Stream_SealLength(cs);
557
Stream_SetPosition(cs, 0);
561
fprintf(stderr, "decompress_rdp() failed\n");
565
Stream_Seek(s, compressed_len - 18);
568
#ifdef WITH_DEBUG_RDP
569
/* if (type != DATA_PDU_TYPE_UPDATE) */
570
DEBUG_RDP("recv %s Data PDU (0x%02X), length:%d",
571
type < ARRAYSIZE(DATA_PDU_TYPE_STRINGS) ? DATA_PDU_TYPE_STRINGS[type] : "???", type, length);
576
case DATA_PDU_TYPE_UPDATE:
577
if (!update_recv(rdp->update, cs))
581
case DATA_PDU_TYPE_CONTROL:
582
if (!rdp_recv_server_control_pdu(rdp, cs))
586
case DATA_PDU_TYPE_POINTER:
587
if (!update_recv_pointer(rdp->update, cs))
591
case DATA_PDU_TYPE_INPUT:
594
case DATA_PDU_TYPE_SYNCHRONIZE:
595
if (!rdp_recv_synchronize_pdu(rdp, cs))
599
case DATA_PDU_TYPE_REFRESH_RECT:
602
case DATA_PDU_TYPE_PLAY_SOUND:
603
if (!update_recv_play_sound(rdp->update, cs))
607
case DATA_PDU_TYPE_SUPPRESS_OUTPUT:
610
case DATA_PDU_TYPE_SHUTDOWN_REQUEST:
613
case DATA_PDU_TYPE_SHUTDOWN_DENIED:
616
case DATA_PDU_TYPE_SAVE_SESSION_INFO:
617
if (!rdp_recv_save_session_info(rdp, cs))
621
case DATA_PDU_TYPE_FONT_LIST:
624
case DATA_PDU_TYPE_FONT_MAP:
625
if (!rdp_recv_font_map_pdu(rdp, cs))
629
case DATA_PDU_TYPE_SET_KEYBOARD_INDICATORS:
632
case DATA_PDU_TYPE_BITMAP_CACHE_PERSISTENT_LIST:
635
case DATA_PDU_TYPE_BITMAP_CACHE_ERROR:
638
case DATA_PDU_TYPE_SET_KEYBOARD_IME_STATUS:
641
case DATA_PDU_TYPE_OFFSCREEN_CACHE_ERROR:
644
case DATA_PDU_TYPE_SET_ERROR_INFO:
645
if (!rdp_recv_set_error_info_data_pdu(rdp, cs))
649
case DATA_PDU_TYPE_DRAW_NINEGRID_ERROR:
652
case DATA_PDU_TYPE_DRAW_GDIPLUS_ERROR:
655
case DATA_PDU_TYPE_ARC_STATUS:
658
case DATA_PDU_TYPE_STATUS_INFO:
661
case DATA_PDU_TYPE_MONITOR_LAYOUT:
674
BOOL rdp_recv_out_of_sequence_pdu(rdpRdp* rdp, wStream* s)
680
if (!rdp_read_share_control_header(s, &length, &type, &channelId))
683
if (type == PDU_TYPE_DATA)
685
return (rdp_recv_data_pdu(rdp, s) < 0) ? FALSE : TRUE;
687
else if (type == PDU_TYPE_SERVER_REDIRECTION)
689
return rdp_recv_enhanced_security_redirection_packet(rdp, s);
698
* Decrypt an RDP packet.\n
699
* @param rdp RDP module
704
BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, int length, UINT16 securityFlags)
709
if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
715
if (Stream_GetRemainingLength(s) < 12)
718
Stream_Read_UINT16(s, len); /* 0x10 */
719
Stream_Read_UINT8(s, version); /* 0x1 */
720
Stream_Read_UINT8(s, pad);
722
sig = Stream_Pointer(s);
723
Stream_Seek(s, 8); /* signature */
727
if (!security_fips_decrypt(Stream_Pointer(s), length, rdp))
729
fprintf(stderr, "FATAL: cannot decrypt\n");
730
return FALSE; /* TODO */
733
if (!security_fips_check_signature(Stream_Pointer(s), length - pad, sig, rdp))
735
fprintf(stderr, "FATAL: invalid packet signature\n");
736
return FALSE; /* TODO */
739
/* is this what needs adjusting? */
740
Stream_Capacity(s) -= pad;
744
if (Stream_GetRemainingLength(s) < 8)
747
Stream_Read(s, wmac, sizeof(wmac));
748
length -= sizeof(wmac);
750
if (!security_decrypt(Stream_Pointer(s), length, rdp))
753
if (securityFlags & SEC_SECURE_CHECKSUM)
754
security_salted_mac_signature(rdp, Stream_Pointer(s), length, FALSE, cmac);
756
security_mac_signature(rdp, Stream_Pointer(s), length, cmac);
758
if (memcmp(wmac, cmac, sizeof(wmac)) != 0)
760
fprintf(stderr, "WARNING: invalid packet signature\n");
762
* Because Standard RDP Security is totally broken,
763
* and cannot protect against MITM, don't treat signature
764
* verification failure as critical. This at least enables
765
* us to work with broken RDP clients and servers that
766
* generate invalid signatures.
775
* Process an RDP packet.\n
776
* @param rdp RDP module
780
static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s)
787
UINT16 securityFlags;
790
if (!rdp_read_header(rdp, s, &length, &channelId))
792
fprintf(stderr, "Incorrect RDP header.\n");
796
if (rdp->settings->DisableEncryption)
798
if (!rdp_read_security_header(s, &securityFlags))
801
if (securityFlags & (SEC_ENCRYPT | SEC_REDIRECTION_PKT))
803
if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
805
fprintf(stderr, "rdp_decrypt failed\n");
810
if (securityFlags & SEC_REDIRECTION_PKT)
813
* [MS-RDPBCGR] 2.2.13.2.1
814
* - no share control header, nor the 2 byte pad
817
rdp_recv_enhanced_security_redirection_packet(rdp, s);
822
if (channelId != MCS_GLOBAL_CHANNEL_ID)
824
if (!freerdp_channel_process(rdp->instance, s, channelId))
829
while (Stream_GetRemainingLength(s) > 3)
831
nextPosition = Stream_GetPosition(s);
833
if (!rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource))
836
nextPosition += pduLength;
838
rdp->settings->PduSource = pduSource;
843
if (rdp_recv_data_pdu(rdp, s) < 0)
845
fprintf(stderr, "rdp_recv_data_pdu failed\n");
850
case PDU_TYPE_DEACTIVATE_ALL:
851
if (!rdp_recv_deactivate_all(rdp, s))
855
case PDU_TYPE_SERVER_REDIRECTION:
856
if (!rdp_recv_enhanced_security_redirection_packet(rdp, s))
861
fprintf(stderr, "incorrect PDU type: 0x%04X\n", pduType);
865
Stream_SetPosition(s, nextPosition);
872
static int rdp_recv_fastpath_pdu(rdpRdp* rdp, wStream* s)
875
rdpFastPath* fastpath;
877
fastpath = rdp->fastpath;
879
if (!fastpath_read_header_rdp(fastpath, s, &length))
882
if ((length == 0) || (length > Stream_GetRemainingLength(s)))
884
fprintf(stderr, "incorrect FastPath PDU header length %d\n", length);
888
if (fastpath->encryptionFlags & FASTPATH_OUTPUT_ENCRYPTED)
890
UINT16 flags = (fastpath->encryptionFlags & FASTPATH_OUTPUT_SECURE_CHECKSUM) ? SEC_SECURE_CHECKSUM : 0;
892
if (!rdp_decrypt(rdp, s, length, flags))
896
return fastpath_recv_updates(rdp->fastpath, s);
899
static int rdp_recv_pdu(rdpRdp* rdp, wStream* s)
901
if (tpkt_verify_header(s))
902
return rdp_recv_tpkt_pdu(rdp, s);
904
return rdp_recv_fastpath_pdu(rdp, s);
907
static int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra)
910
rdpRdp* rdp = (rdpRdp*) extra;
914
case CONNECTION_STATE_NEGO:
915
if (!rdp_client_connect_mcs_connect_response(rdp, s))
919
case CONNECTION_STATE_MCS_ATTACH_USER:
920
if (!rdp_client_connect_mcs_attach_user_confirm(rdp, s))
924
case CONNECTION_STATE_MCS_CHANNEL_JOIN:
925
if (!rdp_client_connect_mcs_channel_join_confirm(rdp, s))
929
case CONNECTION_STATE_LICENSE:
930
if (!rdp_client_connect_license(rdp, s))
934
case CONNECTION_STATE_CAPABILITY:
935
if (!rdp_client_connect_demand_active(rdp, s))
939
case CONNECTION_STATE_FINALIZATION:
940
status = rdp_recv_pdu(rdp, s);
941
if ((status >= 0) && (rdp->finalize_sc_pdus == FINALIZE_SC_COMPLETE))
942
rdp->state = CONNECTION_STATE_ACTIVE;
945
case CONNECTION_STATE_ACTIVE:
946
status = rdp_recv_pdu(rdp, s);
950
fprintf(stderr, "Invalid state %d\n", rdp->state);
958
int rdp_send_channel_data(rdpRdp* rdp, int channel_id, BYTE* data, int size)
960
return freerdp_channel_send(rdp, channel_id, data, size);
964
* Set non-blocking mode information.
965
* @param rdp RDP module
966
* @param blocking blocking mode
968
void rdp_set_blocking_mode(rdpRdp* rdp, BOOL blocking)
970
rdp->transport->ReceiveCallback = rdp_recv_callback;
971
rdp->transport->ReceiveExtra = rdp;
972
transport_set_blocking_mode(rdp->transport, blocking);
975
int rdp_check_fds(rdpRdp* rdp)
977
return transport_check_fds(&(rdp->transport));
981
* Instantiate new RDP module.
982
* @return new RDP module
985
rdpRdp* rdp_new(freerdp* instance)
989
rdp = (rdpRdp*) malloc(sizeof(rdpRdp));
993
ZeroMemory(rdp, sizeof(rdpRdp));
995
rdp->instance = instance;
996
rdp->settings = freerdp_settings_new((void*) instance);
998
if (instance != NULL)
999
instance->settings = rdp->settings;
1001
rdp->extension = extension_new(instance);
1002
rdp->transport = transport_new(rdp->settings);
1003
rdp->license = license_new(rdp);
1004
rdp->input = input_new(rdp);
1005
rdp->update = update_new(rdp);
1006
rdp->fastpath = fastpath_new(rdp);
1007
rdp->nego = nego_new(rdp->transport);
1008
rdp->mcs = mcs_new(rdp->transport);
1009
rdp->redirection = redirection_new();
1010
rdp->mppc_dec = mppc_dec_new();
1011
rdp->mppc_enc = mppc_enc_new(PROTO_RDP_50);
1019
* @param rdp RDP module to be freed
1022
void rdp_free(rdpRdp* rdp)
1026
crypto_rc4_free(rdp->rc4_decrypt_key);
1027
crypto_rc4_free(rdp->rc4_encrypt_key);
1028
crypto_des3_free(rdp->fips_encrypt);
1029
crypto_des3_free(rdp->fips_decrypt);
1030
crypto_hmac_free(rdp->fips_hmac);
1031
freerdp_settings_free(rdp->settings);
1032
extension_free(rdp->extension);
1033
transport_free(rdp->transport);
1034
license_free(rdp->license);
1035
input_free(rdp->input);
1036
update_free(rdp->update);
1037
fastpath_free(rdp->fastpath);
1038
nego_free(rdp->nego);
1040
redirection_free(rdp->redirection);
1041
mppc_dec_free(rdp->mppc_dec);
1042
mppc_enc_free(rdp->mppc_enc);