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 "transport.h"
24 #include <freerdp/types.h>
25 #include <freerdp/settings.h>
26 #include <freerdp/utils/blob.h>
27 #include <freerdp/utils/debug.h>
28 #include <freerdp/utils/stream.h>
30 /* Protocol Security Negotiation Protocols */
31 enum RDP_NEG_PROTOCOLS
33 PROTOCOL_RDP = 0x00000000,
34 PROTOCOL_TLS = 0x00000001,
35 PROTOCOL_NLA = 0x00000002
38 /* Protocol Security Negotiation Failure Codes */
39 enum RDP_NEG_FAILURE_FAILURECODES
41 SSL_REQUIRED_BY_SERVER = 0x00000001,
42 SSL_NOT_ALLOWED_BY_SERVER = 0x00000002,
43 SSL_CERT_NOT_ON_SERVER = 0x00000003,
44 INCONSISTENT_FLAGS = 0x00000004,
45 HYBRID_REQUIRED_BY_SERVER = 0x00000005
51 NEGO_STATE_NLA, /* Network Level Authentication (TLS implicit) */
52 NEGO_STATE_TLS, /* TLS Encryption without NLA */
53 NEGO_STATE_RDP, /* Standard Legacy RDP Encryption */
54 NEGO_STATE_FAIL, /* Negotiation failure */
57 typedef enum _NEGO_STATE NEGO_STATE;
59 /* RDP Negotiation Messages */
62 /* X224_TPDU_CONNECTION_REQUEST */
63 TYPE_RDP_NEG_REQ = 0x1,
64 /* X224_TPDU_CONNECTION_CONFIRM */
65 TYPE_RDP_NEG_RSP = 0x2,
66 TYPE_RDP_NEG_FAILURE = 0x3
69 #define EXTENDED_CLIENT_DATA_SUPPORTED 0x01
71 #define PRECONNECTION_PDU_V1_SIZE 16
72 #define PRECONNECTION_PDU_V2_MIN_SIZE (PRECONNECTION_PDU_V1_SIZE+2)
74 #define PRECONNECTION_PDU_V1 1
75 #define PRECONNECTION_PDU_V2 2
83 rdpBlob* routing_token;
84 boolean send_preconnection_pdu;
85 uint32 preconnection_id;
86 char* preconnection_blob;
89 boolean tcp_connected;
90 boolean security_connected;
92 uint32 selected_protocol;
93 uint32 requested_protocols;
94 boolean security_layer_negotiation_enabled;
95 uint8 enabled_protocols[3];
97 rdpTransport* transport;
99 typedef struct rdp_nego rdpNego;
101 boolean nego_connect(rdpNego* nego);
103 boolean nego_send_preconnection_pdu(rdpNego* nego);
105 void nego_attempt_nla(rdpNego* nego);
106 void nego_attempt_tls(rdpNego* nego);
107 void nego_attempt_rdp(rdpNego* nego);
109 void nego_send(rdpNego* nego);
110 boolean nego_recv(rdpTransport* transport, STREAM* s, void* extra);
111 boolean nego_recv_response(rdpNego* nego);
112 boolean nego_read_request(rdpNego* nego, STREAM* s);
114 boolean nego_send_negotiation_request(rdpNego* nego);
115 void nego_process_negotiation_request(rdpNego* nego, STREAM* s);
116 void nego_process_negotiation_response(rdpNego* nego, STREAM* s);
117 void nego_process_negotiation_failure(rdpNego* nego, STREAM* s);
118 boolean nego_send_negotiation_response(rdpNego* nego);
120 rdpNego* nego_new(struct rdp_transport * transport);
121 void nego_free(rdpNego* nego);
122 void nego_init(rdpNego* nego);
123 void nego_set_target(rdpNego* nego, char* hostname, int port);
124 void nego_set_negotiation_enabled(rdpNego* nego, boolean security_layer_negotiation_enabled);
125 void nego_enable_rdp(rdpNego* nego, boolean enable_rdp);
126 void nego_enable_nla(rdpNego* nego, boolean enable_nla);
127 void nego_enable_tls(rdpNego* nego, boolean enable_tls);
128 void nego_set_routing_token(rdpNego* nego, rdpBlob* routing_token);
129 void nego_set_cookie(rdpNego* nego, char* cookie);
130 void nego_set_send_preconnection_pdu(rdpNego* nego, boolean send_pcpdu);
131 void nego_set_preconnection_id(rdpNego* nego, uint32 id);
132 void nego_set_preconnection_blob(rdpNego* nego, char* blob);
134 #ifdef WITH_DEBUG_NEGO
135 #define DEBUG_NEGO(fmt, ...) DEBUG_CLASS(NEGO, fmt, ## __VA_ARGS__)
137 #define DEBUG_NEGO(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
140 #endif /* __NEGO_H */