2
* FreeRDP: A Remote Desktop Protocol Client
3
* RDP Protocol Security Negotiation
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.
23
#include <freerdp/constants.h>
24
#include <freerdp/utils/memory.h>
30
static const char* const NEGO_STATE_STRINGS[] =
40
static const char PROTOCOL_SECURITY_STRINGS[3][4] =
48
* Negotiate protocol security and connect.
53
boolean nego_connect(rdpNego* nego)
55
if (nego->state == NEGO_STATE_INITIAL)
57
if (nego->enabled_protocols[PROTOCOL_NLA] > 0)
58
nego->state = NEGO_STATE_NLA;
59
else if (nego->enabled_protocols[PROTOCOL_TLS] > 0)
60
nego->state = NEGO_STATE_TLS;
61
else if (nego->enabled_protocols[PROTOCOL_RDP] > 0)
62
nego->state = NEGO_STATE_RDP;
64
nego->state = NEGO_STATE_FAIL;
69
DEBUG_NEGO("state: %s", NEGO_STATE_STRINGS[nego->state]);
73
if (nego->state == NEGO_STATE_FAIL)
75
DEBUG_NEGO("Protocol Security Negotiation Failure");
76
nego->state = NEGO_STATE_FINAL;
80
while (nego->state != NEGO_STATE_FINAL);
82
DEBUG_NEGO("Negotiated %s security", PROTOCOL_SECURITY_STRINGS[nego->selected_protocol]);
84
/* update settings with negotiated protocol security */
85
nego->transport->settings->requested_protocols = nego->requested_protocols;
86
nego->transport->settings->selected_protocol = nego->selected_protocol;
87
nego->transport->settings->negotiationFlags = nego->flags;
89
if(nego->selected_protocol == PROTOCOL_RDP)
91
nego->transport->settings->encryption = true;
92
nego->transport->settings->encryption_method = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS;
93
nego->transport->settings->encryption_level = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE;
105
boolean nego_tcp_connect(rdpNego* nego)
107
if (nego->tcp_connected == 0)
109
if (transport_connect(nego->transport, nego->hostname, nego->port) == false)
111
nego->tcp_connected = 0;
116
nego->tcp_connected = 1;
125
* Disconnect TCP layer.
130
int nego_tcp_disconnect(rdpNego* nego)
132
if (nego->tcp_connected)
133
transport_disconnect(nego->transport);
135
nego->tcp_connected = 0;
140
* Attempt negotiating NLA + TLS security.
144
void nego_attempt_nla(rdpNego* nego)
146
nego->requested_protocols = PROTOCOL_NLA | PROTOCOL_TLS;
148
DEBUG_NEGO("Attempting NLA security");
150
if (!nego_tcp_connect(nego))
152
nego->state = NEGO_STATE_FAIL;
156
if (!nego_send_negotiation_request(nego))
158
nego->state = NEGO_STATE_FAIL;
162
if (!nego_recv_response(nego))
164
nego->state = NEGO_STATE_FAIL;
168
if (nego->state != NEGO_STATE_FINAL)
170
nego_tcp_disconnect(nego);
172
if (nego->enabled_protocols[PROTOCOL_TLS] > 0)
173
nego->state = NEGO_STATE_TLS;
174
else if (nego->enabled_protocols[PROTOCOL_RDP] > 0)
175
nego->state = NEGO_STATE_RDP;
177
nego->state = NEGO_STATE_FAIL;
182
* Attempt negotiating TLS security.
186
void nego_attempt_tls(rdpNego* nego)
188
nego->requested_protocols = PROTOCOL_TLS;
190
DEBUG_NEGO("Attempting TLS security");
192
if (!nego_tcp_connect(nego))
194
nego->state = NEGO_STATE_FAIL;
198
if (!nego_send_negotiation_request(nego))
200
nego->state = NEGO_STATE_FAIL;
204
if (!nego_recv_response(nego))
206
nego->state = NEGO_STATE_FAIL;
210
if (nego->state != NEGO_STATE_FINAL)
212
nego_tcp_disconnect(nego);
214
if (nego->enabled_protocols[PROTOCOL_RDP] > 0)
215
nego->state = NEGO_STATE_RDP;
217
nego->state = NEGO_STATE_FAIL;
222
* Attempt negotiating standard RDP security.
226
void nego_attempt_rdp(rdpNego* nego)
228
nego->requested_protocols = PROTOCOL_RDP;
230
DEBUG_NEGO("Attempting RDP security");
232
if (!nego_tcp_connect(nego))
234
nego->state = NEGO_STATE_FAIL;
238
if (!nego_send_negotiation_request(nego))
240
nego->state = NEGO_STATE_FAIL;
244
if (!nego_recv_response(nego))
246
nego->state = NEGO_STATE_FAIL;
252
* Wait to receive a negotiation response
256
boolean nego_recv_response(rdpNego* nego)
258
STREAM* s = transport_recv_stream_init(nego->transport, 1024);
259
if (transport_read(nego->transport, s) < 0)
261
return nego_recv(nego->transport, s, nego->transport->recv_extra);
265
* Receive protocol security negotiation message.\n
267
* @param transport transport
269
* @param extra nego pointer
272
boolean nego_recv(rdpTransport* transport, STREAM* s, void* extra)
276
rdpNego* nego = (rdpNego*) extra;
278
if (tpkt_read_header(s) == 0)
281
li = tpdu_read_connection_confirm(s);
285
/* rdpNegData (optional) */
287
stream_read_uint8(s, type); /* Type */
291
case TYPE_RDP_NEG_RSP:
292
nego_process_negotiation_response(nego, s);
295
case TYPE_RDP_NEG_FAILURE:
296
nego_process_negotiation_failure(nego, s);
302
nego->state = NEGO_STATE_FINAL;
309
* Read protocol security negotiation request message.\n
314
boolean nego_read_request(rdpNego* nego, STREAM* s)
321
li = tpdu_read_connection_request(s);
322
if (li != stream_get_left(s) + 6)
324
printf("Incorrect TPDU length indicator.\n");
328
if (stream_get_left(s) > 8)
330
/* Optional routingToken or cookie, ending with CR+LF */
331
while (stream_get_left(s) > 0)
333
stream_read_uint8(s, c);
336
stream_peek_uint8(s, c);
340
stream_seek_uint8(s);
345
if (stream_get_left(s) >= 8)
347
/* rdpNegData (optional) */
349
stream_read_uint8(s, type); /* Type */
350
if (type != TYPE_RDP_NEG_REQ)
352
printf("Incorrect negotiation request type %d\n", type);
356
nego_process_negotiation_request(nego, s);
363
* Send protocol security negotiation message.
367
void nego_send(rdpNego* nego)
369
if (nego->state == NEGO_STATE_NLA)
370
nego_attempt_nla(nego);
371
else if (nego->state == NEGO_STATE_TLS)
372
nego_attempt_tls(nego);
373
else if (nego->state == NEGO_STATE_RDP)
374
nego_attempt_rdp(nego);
376
DEBUG_NEGO("invalid negotiation state for sending");
380
* Send RDP Negotiation Request (RDP_NEG_REQ).\n
386
boolean nego_send_negotiation_request(rdpNego* nego)
392
s = transport_send_stream_init(nego->transport, 256);
393
length = TPDU_CONNECTION_REQUEST_LENGTH;
394
stream_get_mark(s, bm);
395
stream_seek(s, length);
397
if (nego->routing_token != NULL)
399
stream_write(s, nego->routing_token->data, nego->routing_token->length);
400
length += nego->routing_token->length;
402
else if (nego->cookie != NULL)
404
int cookie_length = strlen(nego->cookie);
405
stream_write(s, "Cookie: mstshash=", 17);
406
stream_write(s, (uint8*)nego->cookie, cookie_length);
407
stream_write_uint8(s, 0x0D); /* CR */
408
stream_write_uint8(s, 0x0A); /* LF */
409
length += cookie_length + 19;
412
if (nego->requested_protocols > PROTOCOL_RDP)
414
/* RDP_NEG_DATA must be present for TLS and NLA */
415
stream_write_uint8(s, TYPE_RDP_NEG_REQ);
416
stream_write_uint8(s, 0); /* flags, must be set to zero */
417
stream_write_uint16(s, 8); /* RDP_NEG_DATA length (8) */
418
stream_write_uint32(s, nego->requested_protocols); /* requestedProtocols */
422
stream_get_mark(s, em);
423
stream_set_mark(s, bm);
424
tpkt_write_header(s, length);
425
tpdu_write_connection_request(s, length - 5);
426
stream_set_mark(s, em);
428
if (transport_write(nego->transport, s) < 0)
435
* Process Negotiation Request from Connection Request message.
440
void nego_process_negotiation_request(rdpNego* nego, STREAM* s)
445
DEBUG_NEGO("RDP_NEG_REQ");
447
stream_read_uint8(s, flags);
448
stream_read_uint16(s, length);
449
stream_read_uint32(s, nego->requested_protocols);
451
nego->state = NEGO_STATE_FINAL;
455
* Process Negotiation Response from Connection Confirm message.
460
void nego_process_negotiation_response(rdpNego* nego, STREAM* s)
464
DEBUG_NEGO("RDP_NEG_RSP");
466
stream_read_uint8(s, nego->flags);
467
stream_read_uint16(s, length);
468
stream_read_uint32(s, nego->selected_protocol);
470
nego->state = NEGO_STATE_FINAL;
474
* Process Negotiation Failure from Connection Confirm message.
479
void nego_process_negotiation_failure(rdpNego* nego, STREAM* s)
485
DEBUG_NEGO("RDP_NEG_FAILURE");
487
stream_read_uint8(s, flags);
488
stream_read_uint16(s, length);
489
stream_read_uint32(s, failureCode);
493
case SSL_REQUIRED_BY_SERVER:
494
DEBUG_NEGO("Error: SSL_REQUIRED_BY_SERVER");
496
case SSL_NOT_ALLOWED_BY_SERVER:
497
DEBUG_NEGO("Error: SSL_NOT_ALLOWED_BY_SERVER");
499
case SSL_CERT_NOT_ON_SERVER:
500
DEBUG_NEGO("Error: SSL_CERT_NOT_ON_SERVER");
502
case INCONSISTENT_FLAGS:
503
DEBUG_NEGO("Error: INCONSISTENT_FLAGS");
505
case HYBRID_REQUIRED_BY_SERVER:
506
DEBUG_NEGO("Error: HYBRID_REQUIRED_BY_SERVER");
509
DEBUG_NEGO("Error: Unknown protocol security error %d", failureCode);
513
nego->state = NEGO_STATE_FAIL;
517
* Send RDP Negotiation Response (RDP_NEG_RSP).\n
521
boolean nego_send_negotiation_response(rdpNego* nego)
527
s = transport_send_stream_init(nego->transport, 256);
528
length = TPDU_CONNECTION_CONFIRM_LENGTH;
529
stream_get_mark(s, bm);
530
stream_seek(s, length);
532
if (nego->selected_protocol > PROTOCOL_RDP)
534
/* RDP_NEG_DATA must be present for TLS and NLA */
535
stream_write_uint8(s, TYPE_RDP_NEG_RSP);
536
stream_write_uint8(s, EXTENDED_CLIENT_DATA_SUPPORTED); /* flags */
537
stream_write_uint16(s, 8); /* RDP_NEG_DATA length (8) */
538
stream_write_uint32(s, nego->selected_protocol); /* selectedProtocol */
542
stream_get_mark(s, em);
543
stream_set_mark(s, bm);
544
tpkt_write_header(s, length);
545
tpdu_write_connection_confirm(s, length - 5);
546
stream_set_mark(s, em);
548
if (transport_write(nego->transport, s) < 0)
551
/* update settings with negotiated protocol security */
552
nego->transport->settings->requested_protocols = nego->requested_protocols;
553
nego->transport->settings->selected_protocol = nego->selected_protocol;
559
* Initialize NEGO state machine.
563
void nego_init(rdpNego* nego)
565
nego->state = NEGO_STATE_INITIAL;
566
nego->requested_protocols = PROTOCOL_RDP;
567
nego->transport->recv_callback = nego_recv;
568
nego->transport->recv_extra = (void*) nego;
573
* Create a new NEGO state machine instance.
578
rdpNego* nego_new(struct rdp_transport * transport)
580
rdpNego* nego = (rdpNego*) xzalloc(sizeof(rdpNego));
584
nego->transport = transport;
592
* Free NEGO state machine.
596
void nego_free(rdpNego* nego)
602
* Set target hostname and port.
608
void nego_set_target(rdpNego* nego, char* hostname, int port)
610
nego->hostname = hostname;
615
* Enable RDP security protocol.
616
* @param nego pointer to the negotiation structure
617
* @param enable_rdp whether to enable normal RDP protocol (true for enabled, false for disabled)
620
void nego_enable_rdp(rdpNego* nego, boolean enable_rdp)
622
DEBUG_NEGO("Enabling RDP security: %s", enable_rdp ? "true" : "false");
623
nego->enabled_protocols[PROTOCOL_RDP] = enable_rdp;
627
* Enable TLS security protocol.
628
* @param nego pointer to the negotiation structure
629
* @param enable_tls whether to enable TLS + RDP protocol (true for enabled, false for disabled)
631
void nego_enable_tls(rdpNego* nego, boolean enable_tls)
633
DEBUG_NEGO("Enabling TLS security: %s", enable_tls ? "true" : "false");
634
nego->enabled_protocols[PROTOCOL_TLS] = enable_tls;
639
* Enable NLA security protocol.
640
* @param nego pointer to the negotiation structure
641
* @param enable_nla whether to enable network level authentication protocol (true for enabled, false for disabled)
644
void nego_enable_nla(rdpNego* nego, boolean enable_nla)
646
DEBUG_NEGO("Enabling NLA security: %s", enable_nla ? "true" : "false");
647
nego->enabled_protocols[PROTOCOL_NLA] = enable_nla;
653
* @param routing_token
656
void nego_set_routing_token(rdpNego* nego, rdpBlob* routing_token)
658
nego->routing_token = routing_token;
667
void nego_set_cookie(rdpNego* nego, char* cookie)
669
nego->cookie = cookie;