@@ -60,20 +60,7 @@ protocol_mask_to_str(int protocol, char *buff, int bufflen)
60
60
BITMASK_STRING_END_OF_LIST
61
61
};
62
62
63
- int rlen = g_bitmask_to_str (protocol , bits , delim , buff , bufflen );
64
-
65
- /* Append "RDP" */
66
- if (rlen == 0 )
67
- {
68
- /* String is empty */
69
- rlen = g_snprintf (buff , bufflen , "RDP" );
70
- }
71
- else if (rlen > 0 && rlen < bufflen )
72
- {
73
- rlen += g_snprintf (buff + rlen , bufflen - rlen , "%cRDP" , delim );
74
- }
75
-
76
- return rlen ;
63
+ return g_bitmask_to_str (protocol , bits , delim , buff , bufflen );
77
64
}
78
65
79
66
/*****************************************************************************/
@@ -105,96 +92,98 @@ xrdp_iso_delete(struct xrdp_iso *self)
105
92
static int
106
93
xrdp_iso_negotiate_security (struct xrdp_iso * self )
107
94
{
108
- char requested_str [64 ];
109
- const char * selected_str = "" ;
110
- const char * configured_str = "" ;
111
-
112
95
int rv = 0 ;
113
96
struct xrdp_client_info * client_info = & (self -> mcs_layer -> sec_layer -> rdp_layer -> client_info );
97
+ char protostr [64 ];
98
+ int got_protocol = 0 ;
99
+ int security_type_mask ;
114
100
115
- /* Can we do TLS/SSL? (basic check) */
116
- int ssl_capable = g_file_readable (client_info -> certificate ) &&
117
- g_file_readable (client_info -> key_file );
118
-
119
- /* Work out what's actually configured in xrdp.ini. The
120
- * selection happens later, but we can do some error checking here */
121
- switch (client_info -> security_layer )
101
+ /* Map the configuration from xrdp.ini to a mask of allowed
102
+ * security types ([MS-RDPBCGR] 2.2.1.2.1)
103
+ *
104
+ * There's some oddness around PROTOCOL_RDP. This value is 0,
105
+ * for compatibility reasons, and it's OK for the server to
106
+ * suggest RDP as the fallback protocol if nothing else is
107
+ * agreed on. Nowadays, classic RDP security should
108
+ * not be used, if at all avoidable */
109
+
110
+ /* At present we only support SSL and RDP security */
111
+ if (client_info -> security_layer == SECURITY_LAYER_RDP )
112
+ {
113
+ security_type_mask = PROTOCOL_RDP ;
114
+ }
115
+ else
122
116
{
123
- case PROTOCOL_RDP :
124
- configured_str = "RDP" ;
125
- break ;
117
+ security_type_mask = PROTOCOL_SSL ;
118
+ }
126
119
127
- case PROTOCOL_SSL :
128
- /* We *must* use TLS. Check we can offer it, and it's requested */
129
- if (ssl_capable )
130
- {
131
- configured_str = "SSL" ;
132
- if ((self -> requestedProtocol & PROTOCOL_SSL ) == 0 )
133
- {
134
- LOG (LOG_LEVEL_ERROR , "Server requires TLS for security, "
135
- "but the client did not request TLS." );
136
- self -> failureCode = SSL_REQUIRED_BY_SERVER ;
137
- rv = 1 ; /* error */
138
- }
139
- }
140
- else
120
+ /* Logically 'and' this value with the mask requested by the client, and
121
+ * see what's left */
122
+ protocol_mask_to_str (self -> requestedProtocol , protostr , sizeof (protostr ));
123
+ LOG (LOG_LEVEL_INFO , "Client requested security types (RDP assumed) : %s" ,
124
+ protostr );
125
+ security_type_mask &= self -> requestedProtocol ;
126
+
127
+ /* Is there a match on SSL/TLS? */
128
+ if ((security_type_mask & PROTOCOL_SSL ) != 0 )
129
+ {
130
+ /* Can we do TLS? (basic check) */
131
+ if (g_file_readable (client_info -> certificate ) &&
132
+ g_file_readable (client_info -> key_file ))
133
+ {
134
+ LOG (LOG_LEVEL_INFO , "Selected TLS security" );
135
+ self -> selectedProtocol = PROTOCOL_SSL ;
136
+ got_protocol = 1 ;
137
+ }
138
+ else
139
+ {
140
+ LOG (LOG_LEVEL_WARNING , "Cannot accept TLS connections because "
141
+ "certificate or private key file is not readable. "
142
+ "certificate file: [%s], private key file: [%s]" ,
143
+ client_info -> certificate , client_info -> key_file );
144
+
145
+ /* If we're configured to ONLY use TLS, this is a problem.
146
+ * If not, we can fall back to RDP */
147
+ if (client_info -> security_layer == SECURITY_LAYER_TLS )
141
148
{
142
- configured_str = "" ;
143
- LOG (LOG_LEVEL_ERROR , "Cannot accept TLS connections because "
144
- "certificate or private key file is not readable. "
145
- "certificate file: [%s], private key file: [%s]" ,
146
- client_info -> certificate , client_info -> key_file );
149
+ LOG (LOG_LEVEL_ERROR ,
150
+ "Server requires TLS (security_layer=tls)" );
147
151
self -> failureCode = SSL_CERT_NOT_ON_SERVER ;
148
- rv = 1 ; /* error */
149
- }
150
- break ;
151
- case PROTOCOL_HYBRID :
152
- case PROTOCOL_HYBRID_EX :
153
- default :
154
- /* We don't yet support CredSSP */
155
- if (ssl_capable )
156
- {
157
- configured_str = "SSL|RDP" ;
152
+ rv = 1 ;
158
153
}
159
- else
160
- {
161
- /*
162
- * Tell the user we can't offer TLS, but this isn't fatal */
163
- configured_str = "RDP" ;
164
- LOG (LOG_LEVEL_WARNING , "Cannot accept TLS connections because "
165
- "certificate or private key file is not readable. "
166
- "certificate file: [%s], private key file: [%s]" ,
167
- client_info -> certificate , client_info -> key_file );
168
- }
169
- break ;
170
- }
171
-
172
- /* Currently the choice comes down to RDP or SSL */
173
- if (rv != 0 )
174
- {
175
- self -> selectedProtocol = PROTOCOL_RDP ;
176
- selected_str = "" ;
154
+ }
177
155
}
178
- else if (ssl_capable && (self -> requestedProtocol &
179
- client_info -> security_layer &
180
- PROTOCOL_SSL ) != 0 )
156
+ else if (client_info -> security_layer == SECURITY_LAYER_TLS )
181
157
{
182
- self -> selectedProtocol = PROTOCOL_SSL ;
183
- selected_str = "SSL" ;
158
+ /* We don't have a match on TLS, but we'll accept nothing less */
159
+ LOG (LOG_LEVEL_ERROR , "Server requires TLS (security_layer=tls)" );
160
+ self -> failureCode = SSL_REQUIRED_BY_SERVER ;
161
+ rv = 1 ;
184
162
}
185
- else
163
+
164
+ /* If we haven't got a match so far, and we haven't got a fail,
165
+ * try RDP */
166
+ if (!got_protocol && !rv )
186
167
{
187
- self -> selectedProtocol = PROTOCOL_RDP ;
188
- selected_str = "RDP" ;
168
+ if (g_fips_mode_enabled ())
169
+ {
170
+ /* This is a FIPS-mode machine, and we don't support classic RDP
171
+ * encryption */
172
+ LOG (LOG_LEVEL_ERROR ,
173
+ "Server in FIPS mode requires TLS for security" );
174
+ self -> failureCode = SSL_REQUIRED_BY_SERVER ;
175
+ rv = 1 ; /* error */
176
+ }
177
+ else
178
+ {
179
+ self -> selectedProtocol = PROTOCOL_RDP ;
180
+ LOG (LOG_LEVEL_INFO , "Selected classic RDP security" );
181
+ LOG (LOG_LEVEL_WARNING , "Classic RDP security is not secure -"
182
+ " please configure TLS on the client and server" );
183
+ got_protocol = 1 ;
184
+ }
189
185
}
190
186
191
- protocol_mask_to_str (self -> requestedProtocol ,
192
- requested_str , sizeof (requested_str ));
193
-
194
- LOG (LOG_LEVEL_INFO , "Security protocol: configured [%s], requested [%s],"
195
- " selected [%s]" ,
196
- configured_str , requested_str , selected_str );
197
-
198
187
return rv ;
199
188
}
200
189
0 commit comments