libfreerdp-core: fix server-side protocol security negotiation for TLS + NLA

This commit is contained in:
Marc-André Moreau 2012-06-19 20:10:49 -04:00
parent 23027a5b97
commit baa740d612
2 changed files with 50 additions and 39 deletions

View File

@ -524,6 +524,7 @@ boolean rdp_client_connect_finalize(rdpRdp* rdp)
boolean rdp_server_accept_nego(rdpRdp* rdp, STREAM* s) boolean rdp_server_accept_nego(rdpRdp* rdp, STREAM* s)
{ {
boolean status; boolean status;
rdpSettings* settings = rdp->settings;
transport_set_blocking_mode(rdp->transport, true); transport_set_blocking_mode(rdp->transport, true);
@ -532,41 +533,35 @@ boolean rdp_server_accept_nego(rdpRdp* rdp, STREAM* s)
rdp->nego->selected_protocol = 0; rdp->nego->selected_protocol = 0;
printf("Requested protocols:"); printf("Client Security: NLA:%d TLS:%d RDP:%d\n",
(rdp->nego->requested_protocols & PROTOCOL_NLA) ? 1 : 0,
(rdp->nego->requested_protocols & PROTOCOL_TLS) ? 1 : 0,
(rdp->nego->requested_protocols == PROTOCOL_RDP) ? 1: 0);
if ((rdp->nego->requested_protocols & PROTOCOL_TLS)) printf("Server Security: NLA:%d TLS:%d RDP:%d\n",
settings->nla_security, settings->tls_security, settings->rdp_security);
if ((settings->nla_security) && (rdp->nego->requested_protocols & PROTOCOL_NLA))
{ {
printf(" TLS"); rdp->nego->selected_protocol = PROTOCOL_NLA;
if (rdp->settings->tls_security)
{
printf("(Y)");
rdp->nego->selected_protocol |= PROTOCOL_TLS;
}
else
printf("(n)");
} }
else if ((settings->tls_security) && (rdp->nego->requested_protocols & PROTOCOL_TLS))
if ((rdp->nego->requested_protocols & PROTOCOL_NLA))
{ {
printf(" NLA"); rdp->nego->selected_protocol = PROTOCOL_TLS;
if (rdp->settings->nla_security)
{
printf("(Y)");
rdp->nego->selected_protocol |= PROTOCOL_NLA;
}
else
printf("(n)");
} }
else if ((settings->rdp_security) && (rdp->nego->selected_protocol == PROTOCOL_RDP))
printf(" RDP");
if (rdp->settings->rdp_security && rdp->nego->selected_protocol == 0)
{ {
printf("(Y)");
rdp->nego->selected_protocol = PROTOCOL_RDP; rdp->nego->selected_protocol = PROTOCOL_RDP;
} }
else else
printf("(n)"); {
printf("\n"); printf("Protocol security negotiation failure\n");
}
printf("Negotiated Security: NLA:%d TLS:%d RDP:%d\n",
(rdp->nego->selected_protocol & PROTOCOL_NLA) ? 1 : 0,
(rdp->nego->selected_protocol & PROTOCOL_TLS) ? 1 : 0,
(rdp->nego->selected_protocol == PROTOCOL_RDP) ? 1: 0);
if (!nego_send_negotiation_response(rdp->nego)) if (!nego_send_negotiation_response(rdp->nego))
return false; return false;

View File

@ -297,15 +297,24 @@ boolean nego_recv(rdpTransport* transport, STREAM* s, void* extra)
DEBUG_NEGO("selected_protocol: %d", nego->selected_protocol); DEBUG_NEGO("selected_protocol: %d", nego->selected_protocol);
/* enhanced security selected ? */ /* enhanced security selected ? */
if (nego->selected_protocol) {
if (nego->selected_protocol == PROTOCOL_NLA && if (nego->selected_protocol)
!nego->enabled_protocols[PROTOCOL_NLA]) {
if ((nego->selected_protocol == PROTOCOL_NLA) &&
(!nego->enabled_protocols[PROTOCOL_NLA]))
{
nego->state = NEGO_STATE_FAIL; nego->state = NEGO_STATE_FAIL;
if (nego->selected_protocol == PROTOCOL_TLS && }
!nego->enabled_protocols[PROTOCOL_TLS]) if ((nego->selected_protocol == PROTOCOL_TLS) &&
(!nego->enabled_protocols[PROTOCOL_TLS]))
{
nego->state = NEGO_STATE_FAIL; nego->state = NEGO_STATE_FAIL;
} else if (!nego->enabled_protocols[PROTOCOL_RDP]) }
}
else if (!nego->enabled_protocols[PROTOCOL_RDP])
{
nego->state = NEGO_STATE_FAIL; nego->state = NEGO_STATE_FAIL;
}
break; break;
case TYPE_RDP_NEG_FAILURE: case TYPE_RDP_NEG_FAILURE:
@ -316,6 +325,7 @@ boolean nego_recv(rdpTransport* transport, STREAM* s, void* extra)
else else
{ {
DEBUG_NEGO("no rdpNegData"); DEBUG_NEGO("no rdpNegData");
if (!nego->enabled_protocols[PROTOCOL_RDP]) if (!nego->enabled_protocols[PROTOCOL_RDP])
nego->state = NEGO_STATE_FAIL; nego->state = NEGO_STATE_FAIL;
else else
@ -368,6 +378,7 @@ boolean nego_read_request(rdpNego* nego, STREAM* s)
/* rdpNegData (optional) */ /* rdpNegData (optional) */
stream_read_uint8(s, type); /* Type */ stream_read_uint8(s, type); /* Type */
if (type != TYPE_RDP_NEG_REQ) if (type != TYPE_RDP_NEG_REQ)
{ {
printf("Incorrect negotiation request type %d\n", type); printf("Incorrect negotiation request type %d\n", type);
@ -470,6 +481,8 @@ void nego_process_negotiation_request(rdpNego* nego, STREAM* s)
stream_read_uint16(s, length); stream_read_uint16(s, length);
stream_read_uint32(s, nego->requested_protocols); stream_read_uint32(s, nego->requested_protocols);
DEBUG_NEGO("requested_protocols: %d", nego->requested_protocols);
nego->state = NEGO_STATE_FINAL; nego->state = NEGO_STATE_FINAL;
} }
@ -543,12 +556,13 @@ void nego_process_negotiation_failure(rdpNego* nego, STREAM* s)
boolean nego_send_negotiation_response(rdpNego* nego) boolean nego_send_negotiation_response(rdpNego* nego)
{ {
STREAM* s; STREAM* s;
rdpSettings* settings; uint8* bm;
uint8* em;
int length; int length;
uint8 *bm, *em; boolean status;
boolean ret; rdpSettings* settings;
ret = true; status = true;
settings = nego->transport->settings; settings = nego->transport->settings;
s = transport_send_stream_init(nego->transport, 256); s = transport_send_stream_init(nego->transport, 256);
@ -577,7 +591,7 @@ boolean nego_send_negotiation_response(rdpNego* nego)
printf("nego_send_negotiation_response: client supports only Standard RDP Security\n"); printf("nego_send_negotiation_response: client supports only Standard RDP Security\n");
stream_write_uint32(s, SSL_REQUIRED_BY_SERVER); stream_write_uint32(s, SSL_REQUIRED_BY_SERVER);
length += 8; length += 8;
ret = false; status = false;
} }
stream_get_mark(s, em); stream_get_mark(s, em);
@ -589,7 +603,7 @@ boolean nego_send_negotiation_response(rdpNego* nego)
if (transport_write(nego->transport, s) < 0) if (transport_write(nego->transport, s) < 0)
return false; return false;
if (ret) if (status)
{ {
/* update settings with negotiated protocol security */ /* update settings with negotiated protocol security */
settings->requested_protocols = nego->requested_protocols; settings->requested_protocols = nego->requested_protocols;
@ -600,12 +614,14 @@ boolean nego_send_negotiation_response(rdpNego* nego)
settings->tls_security = false; settings->tls_security = false;
settings->nla_security = false; settings->nla_security = false;
settings->rdp_security = true; settings->rdp_security = true;
if (!settings->local) if (!settings->local)
{ {
settings->encryption = true; settings->encryption = true;
settings->encryption_method = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS; settings->encryption_method = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS;
settings->encryption_level = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE; settings->encryption_level = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE;
} }
if (settings->encryption && settings->server_key == NULL && settings->rdp_key_file == NULL) if (settings->encryption && settings->server_key == NULL && settings->rdp_key_file == NULL)
return false; return false;
} }
@ -629,7 +645,7 @@ boolean nego_send_negotiation_response(rdpNego* nego)
} }
} }
return ret; return status;
} }
/** /**