Add glue that enables server-side support for Standard RDP Security.

This commit is contained in:
Pawel Jakub Dawidek 2012-01-25 17:08:10 +01:00
parent 7207e945c3
commit 31529071fd
4 changed files with 87 additions and 9 deletions

View File

@ -502,11 +502,8 @@ boolean rdp_server_accept_nego(rdpRdp* rdp, STREAM* s)
if (!nego_read_request(rdp->nego, s))
return false;
if (rdp->nego->requested_protocols == PROTOCOL_RDP)
{
printf("Standard RDP encryption is not supported.\n");
return false;
}
rdp->nego->selected_protocol = 0;
printf("Requested protocols:");
if ((rdp->nego->requested_protocols & PROTOCOL_TLS))
@ -531,6 +528,14 @@ boolean rdp_server_accept_nego(rdpRdp* rdp, STREAM* s)
else
printf("(n)");
}
printf(" RDP");
if (rdp->settings->rdp_security && rdp->nego->selected_protocol == 0)
{
printf("(Y)");
rdp->nego->selected_protocol = PROTOCOL_RDP;
}
else
printf("(n)");
printf("\n");
if (!nego_send_negotiation_response(rdp->nego))
@ -632,8 +637,20 @@ boolean rdp_server_accept_mcs_channel_join_request(rdpRdp* rdp, STREAM* s)
return true;
}
boolean rdp_server_accept_client_keys(rdpRdp* rdp, STREAM* s)
{
if (!rdp_server_establish_keys(rdp, s))
return false;
rdp->state = CONNECTION_STATE_ESTABLISH_KEYS;
return true;
}
boolean rdp_server_accept_client_info(rdpRdp* rdp, STREAM* s)
{
if (!rdp_recv_client_info(rdp, s))
return false;

View File

@ -39,6 +39,7 @@ enum CONNECTION_STATE
CONNECTION_STATE_MCS_ERECT_DOMAIN,
CONNECTION_STATE_MCS_ATTACH_USER,
CONNECTION_STATE_MCS_CHANNEL_JOIN,
CONNECTION_STATE_ESTABLISH_KEYS,
CONNECTION_STATE_LICENSE,
CONNECTION_STATE_CAPABILITY,
CONNECTION_STATE_FINALIZATION,
@ -59,6 +60,7 @@ boolean rdp_server_accept_mcs_connect_initial(rdpRdp* rdp, STREAM* s);
boolean rdp_server_accept_mcs_erect_domain_request(rdpRdp* rdp, STREAM* s);
boolean rdp_server_accept_mcs_attach_user_request(rdpRdp* rdp, STREAM* s);
boolean rdp_server_accept_mcs_channel_join_request(rdpRdp* rdp, STREAM* s);
boolean rdp_server_accept_client_keys(rdpRdp* rdp, STREAM* s);
boolean rdp_server_accept_client_info(rdpRdp* rdp, STREAM* s);
boolean rdp_server_accept_confirm_active(rdpRdp* rdp, STREAM* s);
boolean rdp_server_reactivate(rdpRdp* rdp);

View File

@ -521,8 +521,13 @@ void nego_process_negotiation_failure(rdpNego* nego, STREAM* s)
boolean nego_send_negotiation_response(rdpNego* nego)
{
STREAM* s;
rdpSettings* settings;
int length;
uint8 *bm, *em;
boolean ret;
ret = true;
settings = nego->transport->settings;
s = transport_send_stream_init(nego->transport, 256);
length = TPDU_CONNECTION_CONFIRM_LENGTH;
@ -538,6 +543,20 @@ boolean nego_send_negotiation_response(rdpNego* nego)
stream_write_uint32(s, nego->selected_protocol); /* selectedProtocol */
length += 8;
}
else if (!settings->rdp_security)
{
stream_write_uint8(s, TYPE_RDP_NEG_FAILURE);
stream_write_uint8(s, 0); /* flags */
stream_write_uint16(s, 8); /* RDP_NEG_DATA length (8) */
/*
* TODO: Check for other possibilities,
* like SSL_NOT_ALLOWED_BY_SERVER.
*/
printf("nego_send_negotiation_response: client supports only Standard RDP Security\n");
stream_write_uint32(s, SSL_REQUIRED_BY_SERVER);
length += 8;
ret = false;
}
stream_get_mark(s, em);
stream_set_mark(s, bm);
@ -548,11 +567,42 @@ boolean nego_send_negotiation_response(rdpNego* nego)
if (transport_write(nego->transport, s) < 0)
return false;
/* update settings with negotiated protocol security */
nego->transport->settings->requested_protocols = nego->requested_protocols;
nego->transport->settings->selected_protocol = nego->selected_protocol;
if (ret)
{
/* update settings with negotiated protocol security */
settings->requested_protocols = nego->requested_protocols;
settings->selected_protocol = nego->selected_protocol;
return true;
if (settings->selected_protocol == PROTOCOL_RDP)
{
settings->tls_security = false;
settings->nla_security = false;
settings->rdp_security = true;
settings->encryption = true;
settings->encryption_method = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS;
settings->encryption_level = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE;
}
else if (settings->selected_protocol == PROTOCOL_TLS)
{
settings->tls_security = true;
settings->nla_security = false;
settings->rdp_security = false;
settings->encryption = false;
settings->encryption_method = ENCRYPTION_METHOD_NONE;
settings->encryption_level = ENCRYPTION_LEVEL_NONE;
}
else if (settings->selected_protocol == PROTOCOL_NLA)
{
settings->tls_security = true;
settings->nla_security = true;
settings->rdp_security = false;
settings->encryption = false;
settings->encryption_method = ENCRYPTION_METHOD_NONE;
settings->encryption_level = ENCRYPTION_LEVEL_NONE;
}
}
return ret;
}
/**

View File

@ -236,6 +236,15 @@ static boolean peer_recv_callback(rdpTransport* transport, STREAM* s, void* extr
break;
case CONNECTION_STATE_MCS_CHANNEL_JOIN:
if (client->context->rdp->settings->encryption) {
if (!rdp_server_accept_client_keys(client->context->rdp, s))
return false;
break;
}
client->context->rdp->state = CONNECTION_STATE_ESTABLISH_KEYS;
/* FALLTHROUGH */
case CONNECTION_STATE_ESTABLISH_KEYS:
if (!rdp_server_accept_client_info(client->context->rdp, s))
return false;
IFCALL(client->Capabilities, client);