~ubuntu-branches/ubuntu/vivid/freerdp/vivid

« back to all changes in this revision

Viewing changes to libfreerdp/core/rdp.c

  • Committer: Package Import Robot
  • Author(s): Iain Lane
  • Date: 2014-11-11 12:20:50 UTC
  • mfrom: (1.2.5)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: package-import@ubuntu.com-20141111122050-7z628f4ab38qxad5
Tags: upstream-1.1.0~git20140921.1.440916e+dfsg1
ImportĀ upstreamĀ versionĀ 1.1.0~git20140921.1.440916e+dfsg1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * FreeRDP: A Remote Desktop Protocol Implementation
 
3
 * RDP Core
 
4
 *
 
5
 * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
 
6
 *
 
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
 
10
 *
 
11
 *     http://www.apache.org/licenses/LICENSE-2.0
 
12
 *
 
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.
 
18
 */
 
19
 
 
20
#ifdef HAVE_CONFIG_H
 
21
#include "config.h"
 
22
#endif
 
23
 
 
24
#include <winpr/crt.h>
 
25
 
 
26
#include "rdp.h"
 
27
 
 
28
#include "info.h"
 
29
#include "redirection.h"
 
30
 
 
31
#include <freerdp/crypto/per.h>
 
32
 
 
33
#ifdef WITH_DEBUG_RDP
 
34
static const char* const DATA_PDU_TYPE_STRINGS[] =
 
35
{
 
36
                "?", "?", /* 0x00 - 0x01 */
 
37
                "Update", /* 0x02 */
 
38
                "?", "?", "?", "?", "?", "?", "?", "?", /* 0x03 - 0x0A */
 
39
                "?", "?", "?", "?", "?", "?", "?", "?", "?", /* 0x0B - 0x13 */
 
40
                "Control", /* 0x14 */
 
41
                "?", "?", "?", "?", "?", "?", /* 0x15 - 0x1A */
 
42
                "Pointer", /* 0x1B */
 
43
                "Input", /* 0x1C */
 
44
                "?", "?", /* 0x1D - 0x1E */
 
45
                "Synchronize", /* 0x1F */
 
46
                "?", /* 0x20 */
 
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 */
 
56
                "?", /* 0x2A */
 
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 */
 
70
};
 
71
#endif
 
72
 
 
73
/**
 
74
 * Read RDP Security Header.\n
 
75
 * @msdn{cc240579}
 
76
 * @param s stream
 
77
 * @param flags security flags
 
78
 */
 
79
 
 
80
BOOL rdp_read_security_header(wStream* s, UINT16* flags)
 
81
{
 
82
        /* Basic Security Header */
 
83
        if (Stream_GetRemainingLength(s) < 4)
 
84
                return FALSE;
 
85
        Stream_Read_UINT16(s, *flags); /* flags */
 
86
        Stream_Seek(s, 2); /* flagsHi (unused) */
 
87
        return TRUE;
 
88
}
 
89
 
 
90
/**
 
91
 * Write RDP Security Header.\n
 
92
 * @msdn{cc240579}
 
93
 * @param s stream
 
94
 * @param flags security flags
 
95
 */
 
96
 
 
97
void rdp_write_security_header(wStream* s, UINT16 flags)
 
98
{
 
99
        /* Basic Security Header */
 
100
        Stream_Write_UINT16(s, flags); /* flags */
 
101
        Stream_Write_UINT16(s, 0); /* flagsHi (unused) */
 
102
}
 
103
 
 
104
BOOL rdp_read_share_control_header(wStream* s, UINT16* length, UINT16* type, UINT16* channel_id)
 
105
{
 
106
        if (Stream_GetRemainingLength(s) < 2)
 
107
                return FALSE;
 
108
 
 
109
        /* Share Control Header */
 
110
        Stream_Read_UINT16(s, *length); /* totalLength */
 
111
 
 
112
        if (*length - 2 > Stream_GetRemainingLength(s))
 
113
                return FALSE;
 
114
 
 
115
        Stream_Read_UINT16(s, *type); /* pduType */
 
116
        *type &= 0x0F; /* type is in the 4 least significant bits */
 
117
 
 
118
        if (*length > 4)
 
119
                Stream_Read_UINT16(s, *channel_id); /* pduSource */
 
120
        else
 
121
                *channel_id = 0; /* Windows XP can send such short DEACTIVATE_ALL PDUs. */
 
122
 
 
123
        return TRUE;
 
124
}
 
125
 
 
126
void rdp_write_share_control_header(wStream* s, UINT16 length, UINT16 type, UINT16 channel_id)
 
127
{
 
128
        length -= RDP_PACKET_HEADER_MAX_LENGTH;
 
129
 
 
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 */
 
134
}
 
135
 
 
136
BOOL rdp_read_share_data_header(wStream* s, UINT16* length, BYTE* type, UINT32* share_id,
 
137
                                        BYTE *compressed_type, UINT16 *compressed_len)
 
138
{
 
139
        if (Stream_GetRemainingLength(s) < 12)
 
140
                return FALSE;
 
141
 
 
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) */
 
150
        return TRUE;
 
151
}
 
152
 
 
153
void rdp_write_share_data_header(wStream* s, UINT16 length, BYTE type, UINT32 share_id)
 
154
{
 
155
        length -= RDP_PACKET_HEADER_MAX_LENGTH;
 
156
        length -= RDP_SHARE_CONTROL_HEADER_LENGTH;
 
157
        length -= RDP_SHARE_DATA_HEADER_LENGTH;
 
158
 
 
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) */
 
167
}
 
168
 
 
169
static int rdp_security_stream_init(rdpRdp* rdp, wStream* s)
 
170
{
 
171
        if (rdp->do_crypt)
 
172
        {
 
173
                Stream_Seek(s, 12);
 
174
 
 
175
                if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
 
176
                        Stream_Seek(s, 4);
 
177
 
 
178
                rdp->sec_flags |= SEC_ENCRYPT;
 
179
 
 
180
                if (rdp->do_secure_checksum)
 
181
                        rdp->sec_flags |= SEC_SECURE_CHECKSUM;
 
182
        }
 
183
        else if (rdp->sec_flags != 0)
 
184
        {
 
185
                Stream_Seek(s, 4);
 
186
        }
 
187
 
 
188
        return 0;
 
189
}
 
190
 
 
191
int rdp_init_stream(rdpRdp* rdp, wStream* s)
 
192
{
 
193
        Stream_Seek(s, RDP_PACKET_HEADER_MAX_LENGTH);
 
194
        rdp_security_stream_init(rdp, s);
 
195
        return 0;
 
196
}
 
197
 
 
198
wStream* rdp_send_stream_init(rdpRdp* rdp)
 
199
{
 
200
        wStream* s;
 
201
        s = transport_send_stream_init(rdp->transport, 2048);
 
202
        rdp_init_stream(rdp, s);
 
203
        return s;
 
204
}
 
205
 
 
206
int rdp_init_stream_pdu(rdpRdp* rdp, wStream* s)
 
207
{
 
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);
 
211
        return 0;
 
212
}
 
213
 
 
214
int rdp_init_stream_data_pdu(rdpRdp* rdp, wStream* s)
 
215
{
 
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);
 
220
        return 0;
 
221
}
 
222
 
 
223
wStream* rdp_data_pdu_init(rdpRdp* rdp)
 
224
{
 
225
        wStream* s;
 
226
        s = transport_send_stream_init(rdp->transport, 2048);
 
227
        rdp_init_stream_data_pdu(rdp, s);
 
228
        return s;
 
229
}
 
230
 
 
231
/**
 
232
 * Read an RDP packet header.\n
 
233
 * @param rdp rdp module
 
234
 * @param s stream
 
235
 * @param length RDP packet length
 
236
 * @param channel_id channel id
 
237
 */
 
238
 
 
239
BOOL rdp_read_header(rdpRdp* rdp, wStream* s, UINT16* length, UINT16* channel_id)
 
240
{
 
241
        UINT16 initiator;
 
242
        enum DomainMCSPDU MCSPDU;
 
243
 
 
244
        MCSPDU = (rdp->settings->ServerMode) ? DomainMCSPDU_SendDataRequest : DomainMCSPDU_SendDataIndication;
 
245
 
 
246
        if (!mcs_read_domain_mcspdu_header(s, &MCSPDU, length))
 
247
        {
 
248
                if (MCSPDU != DomainMCSPDU_DisconnectProviderUltimatum)
 
249
                        return FALSE;
 
250
        }
 
251
 
 
252
        if (*length - 8 > Stream_GetRemainingLength(s))
 
253
                return FALSE;
 
254
 
 
255
        if (MCSPDU == DomainMCSPDU_DisconnectProviderUltimatum)
 
256
        {
 
257
                BYTE reason;
 
258
                TerminateEventArgs e;
 
259
                rdpContext* context = rdp->instance->context;
 
260
 
 
261
                (void) per_read_enumerated(s, &reason, 0);
 
262
                DEBUG_RDP("DisconnectProviderUltimatum from server, reason code 0x%02x\n", reason);
 
263
 
 
264
                rdp->disconnect = TRUE;
 
265
 
 
266
                EventArgsInit(&e, "freerdp");
 
267
                e.code = 0;
 
268
                PubSub_OnTerminate(context->pubSub, context, &e);
 
269
 
 
270
                return TRUE;
 
271
        }
 
272
 
 
273
        if (Stream_GetRemainingLength(s) < 5)
 
274
                return FALSE;
 
275
 
 
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) */
 
279
 
 
280
        if (!per_read_length(s, length)) /* userData (OCTET_STRING) */
 
281
                return FALSE;
 
282
 
 
283
        if (*length > Stream_GetRemainingLength(s))
 
284
                return FALSE;
 
285
 
 
286
        return TRUE;
 
287
}
 
288
 
 
289
/**
 
290
 * Write an RDP packet header.\n
 
291
 * @param rdp rdp module
 
292
 * @param s stream
 
293
 * @param length RDP packet length
 
294
 * @param channel_id channel id
 
295
 */
 
296
 
 
297
void rdp_write_header(rdpRdp* rdp, wStream* s, UINT16 length, UINT16 channel_id)
 
298
{
 
299
        int body_length;
 
300
        enum DomainMCSPDU MCSPDU;
 
301
 
 
302
        MCSPDU = (rdp->settings->ServerMode) ? DomainMCSPDU_SendDataIndication : DomainMCSPDU_SendDataRequest;
 
303
 
 
304
        if ((rdp->sec_flags & SEC_ENCRYPT) && (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS))
 
305
        {
 
306
                int pad;
 
307
 
 
308
                body_length = length - RDP_PACKET_HEADER_MAX_LENGTH - 16;
 
309
                pad = 8 - (body_length % 8);
 
310
 
 
311
                if (pad != 8)
 
312
                        length += pad;
 
313
        }
 
314
 
 
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 */
 
319
        /*
 
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.
 
324
         */
 
325
        length = (length - RDP_PACKET_HEADER_MAX_LENGTH) | 0x8000;
 
326
        Stream_Write_UINT16_BE(s, length); /* userData (OCTET_STRING) */
 
327
}
 
328
 
 
329
static UINT32 rdp_security_stream_out(rdpRdp* rdp, wStream* s, int length)
 
330
{
 
331
        BYTE* data;
 
332
        UINT32 sec_flags;
 
333
        UINT32 pad = 0;
 
334
 
 
335
        sec_flags = rdp->sec_flags;
 
336
 
 
337
        if (sec_flags != 0)
 
338
        {
 
339
                rdp_write_security_header(s, sec_flags);
 
340
 
 
341
                if (sec_flags & SEC_ENCRYPT)
 
342
                {
 
343
                        if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
 
344
                        {
 
345
                                data = Stream_Pointer(s) + 12;
 
346
 
 
347
                                length = length - (data - Stream_Buffer(s));
 
348
                                Stream_Write_UINT16(s, 0x10); /* length */
 
349
                                Stream_Write_UINT8(s, 0x1); /* TSFIPS_VERSION 1*/
 
350
 
 
351
                                /* handle padding */
 
352
                                pad = 8 - (length % 8);
 
353
 
 
354
                                if (pad == 8)
 
355
                                        pad = 0;
 
356
                                if (pad)
 
357
                                        memset(data+length, 0, pad);
 
358
 
 
359
                                Stream_Write_UINT8(s, pad);
 
360
 
 
361
                                security_hmac_signature(data, length, Stream_Pointer(s), rdp);
 
362
                                Stream_Seek(s, 8);
 
363
                                security_fips_encrypt(data, length + pad, rdp);
 
364
                        }
 
365
                        else
 
366
                        {
 
367
                                data = Stream_Pointer(s) + 8;
 
368
                                length = length - (data - Stream_Buffer(s));
 
369
 
 
370
                                if (sec_flags & SEC_SECURE_CHECKSUM)
 
371
                                        security_salted_mac_signature(rdp, data, length, TRUE, Stream_Pointer(s));
 
372
                                else
 
373
                                        security_mac_signature(rdp, data, length, Stream_Pointer(s));
 
374
 
 
375
                                Stream_Seek(s, 8);
 
376
                                security_encrypt(Stream_Pointer(s), length, rdp);
 
377
                        }
 
378
                }
 
379
 
 
380
                rdp->sec_flags = 0;
 
381
        }
 
382
 
 
383
        return pad;
 
384
}
 
385
 
 
386
static UINT32 rdp_get_sec_bytes(rdpRdp* rdp)
 
387
{
 
388
        UINT32 sec_bytes;
 
389
 
 
390
        if (rdp->sec_flags & SEC_ENCRYPT)
 
391
        {
 
392
                sec_bytes = 12;
 
393
 
 
394
                if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
 
395
                        sec_bytes += 4;
 
396
        }
 
397
        else if (rdp->sec_flags != 0)
 
398
        {
 
399
                sec_bytes = 4;
 
400
        }
 
401
        else
 
402
        {
 
403
                sec_bytes = 0;
 
404
        }
 
405
 
 
406
        return sec_bytes;
 
407
}
 
408
 
 
409
/**
 
410
 * Send an RDP packet.\n
 
411
 * @param rdp RDP module
 
412
 * @param s stream
 
413
 * @param channel_id channel id
 
414
 */
 
415
 
 
416
BOOL rdp_send(rdpRdp* rdp, wStream* s, UINT16 channel_id)
 
417
{
 
418
        int secm;
 
419
        UINT16 length;
 
420
        UINT32 sec_bytes;
 
421
 
 
422
        length = Stream_GetPosition(s);
 
423
        Stream_SetPosition(s, 0);
 
424
 
 
425
        rdp_write_header(rdp, s, length, channel_id);
 
426
 
 
427
        sec_bytes = rdp_get_sec_bytes(rdp);
 
428
        secm = Stream_GetPosition(s);
 
429
        Stream_Seek(s, sec_bytes);
 
430
 
 
431
        Stream_SetPosition(s, secm);
 
432
        length += rdp_security_stream_out(rdp, s, length);
 
433
 
 
434
        Stream_SetPosition(s, length);
 
435
        Stream_SealLength(s);
 
436
 
 
437
        if (transport_write(rdp->transport, s) < 0)
 
438
                return FALSE;
 
439
 
 
440
        return TRUE;
 
441
}
 
442
 
 
443
BOOL rdp_send_pdu(rdpRdp* rdp, wStream* s, UINT16 type, UINT16 channel_id)
 
444
{
 
445
        UINT16 length;
 
446
        UINT32 sec_bytes;
 
447
        int sec_hold;
 
448
 
 
449
        length = Stream_GetPosition(s);
 
450
        Stream_SetPosition(s, 0);
 
451
 
 
452
        rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID);
 
453
 
 
454
        sec_bytes = rdp_get_sec_bytes(rdp);
 
455
        sec_hold = Stream_GetPosition(s);
 
456
        Stream_Seek(s, sec_bytes);
 
457
 
 
458
        rdp_write_share_control_header(s, length - sec_bytes, type, channel_id);
 
459
 
 
460
        Stream_SetPosition(s, sec_hold);
 
461
        length += rdp_security_stream_out(rdp, s, length);
 
462
 
 
463
        Stream_SetPosition(s, length);
 
464
        Stream_SealLength(s);
 
465
 
 
466
        if (transport_write(rdp->transport, s) < 0)
 
467
                return FALSE;
 
468
 
 
469
        return TRUE;
 
470
}
 
471
 
 
472
BOOL rdp_send_data_pdu(rdpRdp* rdp, wStream* s, BYTE type, UINT16 channel_id)
 
473
{
 
474
        UINT16 length;
 
475
        UINT32 sec_bytes;
 
476
        int sec_hold;
 
477
 
 
478
        length = Stream_GetPosition(s);
 
479
        Stream_SetPosition(s, 0);
 
480
 
 
481
        rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID);
 
482
 
 
483
        sec_bytes = rdp_get_sec_bytes(rdp);
 
484
        sec_hold = Stream_GetPosition(s);
 
485
        Stream_Seek(s, sec_bytes);
 
486
 
 
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);
 
489
 
 
490
        Stream_SetPosition(s, sec_hold);
 
491
        length += rdp_security_stream_out(rdp, s, length);
 
492
 
 
493
        Stream_SetPosition(s, length);
 
494
        Stream_SealLength(s);
 
495
 
 
496
        if (transport_write(rdp->transport, s) < 0)
 
497
                return FALSE;
 
498
 
 
499
        return TRUE;
 
500
}
 
501
 
 
502
BOOL rdp_recv_set_error_info_data_pdu(rdpRdp* rdp, wStream* s)
 
503
{
 
504
        if (Stream_GetRemainingLength(s) < 4)
 
505
                return FALSE;
 
506
 
 
507
        Stream_Read_UINT32(s, rdp->errorInfo); /* errorInfo (4 bytes) */
 
508
 
 
509
        if (rdp->errorInfo != ERRINFO_SUCCESS)
 
510
        {
 
511
                ErrorInfoEventArgs e;
 
512
                rdpContext* context = rdp->instance->context;
 
513
 
 
514
                rdp_print_errinfo(rdp->errorInfo);
 
515
 
 
516
                EventArgsInit(&e, "freerdp");
 
517
                e.code = rdp->errorInfo;
 
518
                PubSub_OnErrorInfo(context->pubSub, context, &e);
 
519
        }
 
520
 
 
521
        return TRUE;
 
522
}
 
523
 
 
524
int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s)
 
525
{
 
526
        BYTE type;
 
527
        UINT32 roff;
 
528
        UINT32 rlen;
 
529
        wStream* cs;
 
530
        BYTE* buffer;
 
531
        UINT16 length;
 
532
        UINT32 share_id;
 
533
        BYTE compressed_type;
 
534
        UINT16 compressed_len;
 
535
 
 
536
        if (!rdp_read_share_data_header(s, &length, &type, &share_id, &compressed_type, &compressed_len))
 
537
                return -1;
 
538
 
 
539
        cs = s;
 
540
 
 
541
        if (compressed_type & PACKET_COMPRESSED)
 
542
        {
 
543
                if (Stream_GetRemainingLength(s) < compressed_len - 18)
 
544
                {
 
545
                        fprintf(stderr, "decompress_rdp: not enough bytes for compressed_len=%d\n", compressed_len);
 
546
                        return -1;      
 
547
                }
 
548
 
 
549
                if (decompress_rdp(rdp->mppc_dec, Stream_Pointer(s), compressed_len - 18, compressed_type, &roff, &rlen))
 
550
                {
 
551
                        buffer = rdp->mppc_dec->history_buf + roff;
 
552
                        cs = StreamPool_Take(rdp->transport->ReceivePool, rlen);
 
553
 
 
554
                        Stream_SetPosition(cs, 0);
 
555
                        Stream_Write(cs, buffer, rlen);
 
556
                        Stream_SealLength(cs);
 
557
                        Stream_SetPosition(cs, 0);
 
558
                }
 
559
                else
 
560
                {
 
561
                        fprintf(stderr, "decompress_rdp() failed\n");
 
562
                        return -1;
 
563
                }
 
564
 
 
565
                Stream_Seek(s, compressed_len - 18);
 
566
        }
 
567
 
 
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);
 
572
#endif
 
573
 
 
574
        switch (type)
 
575
        {
 
576
                case DATA_PDU_TYPE_UPDATE:
 
577
                        if (!update_recv(rdp->update, cs))
 
578
                                return -1;
 
579
                        break;
 
580
 
 
581
                case DATA_PDU_TYPE_CONTROL:
 
582
                        if (!rdp_recv_server_control_pdu(rdp, cs))
 
583
                                return -1;
 
584
                        break;
 
585
 
 
586
                case DATA_PDU_TYPE_POINTER:
 
587
                        if (!update_recv_pointer(rdp->update, cs))
 
588
                                return -1;
 
589
                        break;
 
590
 
 
591
                case DATA_PDU_TYPE_INPUT:
 
592
                        break;
 
593
 
 
594
                case DATA_PDU_TYPE_SYNCHRONIZE:
 
595
                        if (!rdp_recv_synchronize_pdu(rdp, cs))
 
596
                                return -1;
 
597
                        break;
 
598
 
 
599
                case DATA_PDU_TYPE_REFRESH_RECT:
 
600
                        break;
 
601
 
 
602
                case DATA_PDU_TYPE_PLAY_SOUND:
 
603
                        if (!update_recv_play_sound(rdp->update, cs))
 
604
                                return -1;
 
605
                        break;
 
606
 
 
607
                case DATA_PDU_TYPE_SUPPRESS_OUTPUT:
 
608
                        break;
 
609
 
 
610
                case DATA_PDU_TYPE_SHUTDOWN_REQUEST:
 
611
                        break;
 
612
 
 
613
                case DATA_PDU_TYPE_SHUTDOWN_DENIED:
 
614
                        break;
 
615
 
 
616
                case DATA_PDU_TYPE_SAVE_SESSION_INFO:
 
617
                        if (!rdp_recv_save_session_info(rdp, cs))
 
618
                                return -1;
 
619
                        break;
 
620
 
 
621
                case DATA_PDU_TYPE_FONT_LIST:
 
622
                        break;
 
623
 
 
624
                case DATA_PDU_TYPE_FONT_MAP:
 
625
                        if (!rdp_recv_font_map_pdu(rdp, cs))
 
626
                                return -1;
 
627
                        break;
 
628
 
 
629
                case DATA_PDU_TYPE_SET_KEYBOARD_INDICATORS:
 
630
                        break;
 
631
 
 
632
                case DATA_PDU_TYPE_BITMAP_CACHE_PERSISTENT_LIST:
 
633
                        break;
 
634
 
 
635
                case DATA_PDU_TYPE_BITMAP_CACHE_ERROR:
 
636
                        break;
 
637
 
 
638
                case DATA_PDU_TYPE_SET_KEYBOARD_IME_STATUS:
 
639
                        break;
 
640
 
 
641
                case DATA_PDU_TYPE_OFFSCREEN_CACHE_ERROR:
 
642
                        break;
 
643
 
 
644
                case DATA_PDU_TYPE_SET_ERROR_INFO:
 
645
                        if (!rdp_recv_set_error_info_data_pdu(rdp, cs))
 
646
                                return -1;
 
647
                        break;
 
648
 
 
649
                case DATA_PDU_TYPE_DRAW_NINEGRID_ERROR:
 
650
                        break;
 
651
 
 
652
                case DATA_PDU_TYPE_DRAW_GDIPLUS_ERROR:
 
653
                        break;
 
654
 
 
655
                case DATA_PDU_TYPE_ARC_STATUS:
 
656
                        break;
 
657
 
 
658
                case DATA_PDU_TYPE_STATUS_INFO:
 
659
                        break;
 
660
 
 
661
                case DATA_PDU_TYPE_MONITOR_LAYOUT:
 
662
                        break;
 
663
 
 
664
                default:
 
665
                        break;
 
666
        }
 
667
 
 
668
        if (cs != s)
 
669
                Stream_Release(cs);
 
670
 
 
671
        return 0;
 
672
}
 
673
 
 
674
BOOL rdp_recv_out_of_sequence_pdu(rdpRdp* rdp, wStream* s)
 
675
{
 
676
        UINT16 type;
 
677
        UINT16 length;
 
678
        UINT16 channelId;
 
679
 
 
680
        if (!rdp_read_share_control_header(s, &length, &type, &channelId))
 
681
                return FALSE;
 
682
 
 
683
        if (type == PDU_TYPE_DATA)
 
684
        {
 
685
                return (rdp_recv_data_pdu(rdp, s) < 0) ? FALSE : TRUE;
 
686
        }
 
687
        else if (type == PDU_TYPE_SERVER_REDIRECTION)
 
688
        {
 
689
                return rdp_recv_enhanced_security_redirection_packet(rdp, s);
 
690
        }
 
691
        else
 
692
        {
 
693
                return FALSE;
 
694
        }
 
695
}
 
696
 
 
697
/**
 
698
 * Decrypt an RDP packet.\n
 
699
 * @param rdp RDP module
 
700
 * @param s stream
 
701
 * @param length int
 
702
 */
 
703
 
 
704
BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, int length, UINT16 securityFlags)
 
705
{
 
706
        BYTE cmac[8];
 
707
        BYTE wmac[8];
 
708
 
 
709
        if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
 
710
        {
 
711
                UINT16 len;
 
712
                BYTE version, pad;
 
713
                BYTE* sig;
 
714
 
 
715
                if (Stream_GetRemainingLength(s) < 12)
 
716
                        return FALSE;
 
717
 
 
718
                Stream_Read_UINT16(s, len); /* 0x10 */
 
719
                Stream_Read_UINT8(s, version); /* 0x1 */
 
720
                Stream_Read_UINT8(s, pad);
 
721
 
 
722
                sig = Stream_Pointer(s);
 
723
                Stream_Seek(s, 8);      /* signature */
 
724
 
 
725
                length -= 12;
 
726
 
 
727
                if (!security_fips_decrypt(Stream_Pointer(s), length, rdp))
 
728
                {
 
729
                        fprintf(stderr, "FATAL: cannot decrypt\n");
 
730
                        return FALSE; /* TODO */
 
731
                }
 
732
 
 
733
                if (!security_fips_check_signature(Stream_Pointer(s), length - pad, sig, rdp))
 
734
                {
 
735
                        fprintf(stderr, "FATAL: invalid packet signature\n");
 
736
                        return FALSE; /* TODO */
 
737
                }
 
738
 
 
739
                /* is this what needs adjusting? */
 
740
                Stream_Capacity(s) -= pad;
 
741
                return TRUE;
 
742
        }
 
743
 
 
744
        if (Stream_GetRemainingLength(s) < 8)
 
745
                return FALSE;
 
746
 
 
747
        Stream_Read(s, wmac, sizeof(wmac));
 
748
        length -= sizeof(wmac);
 
749
 
 
750
        if (!security_decrypt(Stream_Pointer(s), length, rdp))
 
751
                return FALSE;
 
752
 
 
753
        if (securityFlags & SEC_SECURE_CHECKSUM)
 
754
                security_salted_mac_signature(rdp, Stream_Pointer(s), length, FALSE, cmac);
 
755
        else
 
756
                security_mac_signature(rdp, Stream_Pointer(s), length, cmac);
 
757
 
 
758
        if (memcmp(wmac, cmac, sizeof(wmac)) != 0)
 
759
        {
 
760
                fprintf(stderr, "WARNING: invalid packet signature\n");
 
761
                /*
 
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.
 
767
                 */
 
768
                //return FALSE;
 
769
        }
 
770
 
 
771
        return TRUE;
 
772
}
 
773
 
 
774
/**
 
775
 * Process an RDP packet.\n
 
776
 * @param rdp RDP module
 
777
 * @param s stream
 
778
 */
 
779
 
 
780
static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s)
 
781
{
 
782
        UINT16 length;
 
783
        UINT16 pduType;
 
784
        UINT16 pduLength;
 
785
        UINT16 pduSource;
 
786
        UINT16 channelId;
 
787
        UINT16 securityFlags;
 
788
        int nextPosition;
 
789
 
 
790
        if (!rdp_read_header(rdp, s, &length, &channelId))
 
791
        {
 
792
                fprintf(stderr, "Incorrect RDP header.\n");
 
793
                return -1;
 
794
        }
 
795
 
 
796
        if (rdp->settings->DisableEncryption)
 
797
        {
 
798
                if (!rdp_read_security_header(s, &securityFlags))
 
799
                        return -1;
 
800
 
 
801
                if (securityFlags & (SEC_ENCRYPT | SEC_REDIRECTION_PKT))
 
802
                {
 
803
                        if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
 
804
                        {
 
805
                                fprintf(stderr, "rdp_decrypt failed\n");
 
806
                                return -1;
 
807
                        }
 
808
                }
 
809
 
 
810
                if (securityFlags & SEC_REDIRECTION_PKT)
 
811
                {
 
812
                        /*
 
813
                         * [MS-RDPBCGR] 2.2.13.2.1
 
814
                         *  - no share control header, nor the 2 byte pad
 
815
                         */
 
816
                        Stream_Rewind(s, 2);
 
817
                        rdp_recv_enhanced_security_redirection_packet(rdp, s);
 
818
                        return -1;
 
819
                }
 
820
        }
 
821
 
 
822
        if (channelId != MCS_GLOBAL_CHANNEL_ID)
 
823
        {
 
824
                if (!freerdp_channel_process(rdp->instance, s, channelId))
 
825
                        return -1;
 
826
        }
 
827
        else
 
828
        {
 
829
                while (Stream_GetRemainingLength(s) > 3)
 
830
                {
 
831
                        nextPosition = Stream_GetPosition(s);
 
832
 
 
833
                        if (!rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource))
 
834
                                return -1;
 
835
 
 
836
                        nextPosition += pduLength;
 
837
 
 
838
                        rdp->settings->PduSource = pduSource;
 
839
 
 
840
                        switch (pduType)
 
841
                        {
 
842
                                case PDU_TYPE_DATA:
 
843
                                        if (rdp_recv_data_pdu(rdp, s) < 0)
 
844
                                        {
 
845
                                                fprintf(stderr, "rdp_recv_data_pdu failed\n");
 
846
                                                return -1;
 
847
                                        }
 
848
                                        break;
 
849
 
 
850
                                case PDU_TYPE_DEACTIVATE_ALL:
 
851
                                        if (!rdp_recv_deactivate_all(rdp, s))
 
852
                                                return -1;
 
853
                                        break;
 
854
 
 
855
                                case PDU_TYPE_SERVER_REDIRECTION:
 
856
                                        if (!rdp_recv_enhanced_security_redirection_packet(rdp, s))
 
857
                                                return -1;
 
858
                                        break;
 
859
 
 
860
                                default:
 
861
                                        fprintf(stderr, "incorrect PDU type: 0x%04X\n", pduType);
 
862
                                        break;
 
863
                        }
 
864
 
 
865
                        Stream_SetPosition(s, nextPosition);
 
866
                }
 
867
        }
 
868
 
 
869
        return 0;
 
870
}
 
871
 
 
872
static int rdp_recv_fastpath_pdu(rdpRdp* rdp, wStream* s)
 
873
{
 
874
        UINT16 length;
 
875
        rdpFastPath* fastpath;
 
876
 
 
877
        fastpath = rdp->fastpath;
 
878
 
 
879
        if (!fastpath_read_header_rdp(fastpath, s, &length))
 
880
                return -1;
 
881
 
 
882
        if ((length == 0) || (length > Stream_GetRemainingLength(s)))
 
883
        {
 
884
                fprintf(stderr, "incorrect FastPath PDU header length %d\n", length);
 
885
                return -1;
 
886
        }
 
887
 
 
888
        if (fastpath->encryptionFlags & FASTPATH_OUTPUT_ENCRYPTED)
 
889
        {
 
890
                UINT16 flags = (fastpath->encryptionFlags & FASTPATH_OUTPUT_SECURE_CHECKSUM) ? SEC_SECURE_CHECKSUM : 0;
 
891
 
 
892
                if (!rdp_decrypt(rdp, s, length, flags))
 
893
                        return -1;
 
894
        }
 
895
 
 
896
        return fastpath_recv_updates(rdp->fastpath, s);
 
897
}
 
898
 
 
899
static int rdp_recv_pdu(rdpRdp* rdp, wStream* s)
 
900
{
 
901
        if (tpkt_verify_header(s))
 
902
                return rdp_recv_tpkt_pdu(rdp, s);
 
903
        else
 
904
                return rdp_recv_fastpath_pdu(rdp, s);
 
905
}
 
906
 
 
907
static int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra)
 
908
{
 
909
        int status = 0;
 
910
        rdpRdp* rdp = (rdpRdp*) extra;
 
911
 
 
912
        switch (rdp->state)
 
913
        {
 
914
                case CONNECTION_STATE_NEGO:
 
915
                        if (!rdp_client_connect_mcs_connect_response(rdp, s))
 
916
                                status = -1;
 
917
                        break;
 
918
 
 
919
                case CONNECTION_STATE_MCS_ATTACH_USER:
 
920
                        if (!rdp_client_connect_mcs_attach_user_confirm(rdp, s))
 
921
                                status = -1;
 
922
                        break;
 
923
 
 
924
                case CONNECTION_STATE_MCS_CHANNEL_JOIN:
 
925
                        if (!rdp_client_connect_mcs_channel_join_confirm(rdp, s))
 
926
                                status = -1;
 
927
                        break;
 
928
 
 
929
                case CONNECTION_STATE_LICENSE:
 
930
                        if (!rdp_client_connect_license(rdp, s))
 
931
                                status = -1;
 
932
                        break;
 
933
 
 
934
                case CONNECTION_STATE_CAPABILITY:
 
935
                        if (!rdp_client_connect_demand_active(rdp, s))
 
936
                                status = -1;
 
937
                        break;
 
938
 
 
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;
 
943
                        break;
 
944
 
 
945
                case CONNECTION_STATE_ACTIVE:
 
946
                        status = rdp_recv_pdu(rdp, s);
 
947
                        break;
 
948
 
 
949
                default:
 
950
                        fprintf(stderr, "Invalid state %d\n", rdp->state);
 
951
                        status = -1;
 
952
                        break;
 
953
        }
 
954
 
 
955
        return status;
 
956
}
 
957
 
 
958
int rdp_send_channel_data(rdpRdp* rdp, int channel_id, BYTE* data, int size)
 
959
{
 
960
        return freerdp_channel_send(rdp, channel_id, data, size);
 
961
}
 
962
 
 
963
/**
 
964
 * Set non-blocking mode information.
 
965
 * @param rdp RDP module
 
966
 * @param blocking blocking mode
 
967
 */
 
968
void rdp_set_blocking_mode(rdpRdp* rdp, BOOL blocking)
 
969
{
 
970
        rdp->transport->ReceiveCallback = rdp_recv_callback;
 
971
        rdp->transport->ReceiveExtra = rdp;
 
972
        transport_set_blocking_mode(rdp->transport, blocking);
 
973
}
 
974
 
 
975
int rdp_check_fds(rdpRdp* rdp)
 
976
{
 
977
        return transport_check_fds(&(rdp->transport));
 
978
}
 
979
 
 
980
/**
 
981
 * Instantiate new RDP module.
 
982
 * @return new RDP module
 
983
 */
 
984
 
 
985
rdpRdp* rdp_new(freerdp* instance)
 
986
{
 
987
        rdpRdp* rdp;
 
988
 
 
989
        rdp = (rdpRdp*) malloc(sizeof(rdpRdp));
 
990
 
 
991
        if (rdp != NULL)
 
992
        {
 
993
                ZeroMemory(rdp, sizeof(rdpRdp));
 
994
 
 
995
                rdp->instance = instance;
 
996
                rdp->settings = freerdp_settings_new((void*) instance);
 
997
 
 
998
                if (instance != NULL)
 
999
                        instance->settings = rdp->settings;
 
1000
 
 
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);
 
1012
        }
 
1013
 
 
1014
        return rdp;
 
1015
}
 
1016
 
 
1017
/**
 
1018
 * Free RDP module.
 
1019
 * @param rdp RDP module to be freed
 
1020
 */
 
1021
 
 
1022
void rdp_free(rdpRdp* rdp)
 
1023
{
 
1024
        if (rdp != NULL)
 
1025
        {
 
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);
 
1039
                mcs_free(rdp->mcs);
 
1040
                redirection_free(rdp->redirection);
 
1041
                mppc_dec_free(rdp->mppc_dec);
 
1042
                mppc_enc_free(rdp->mppc_enc);
 
1043
                free(rdp);
 
1044
        }
 
1045
}
 
1046