libfreerdp-core: fix server-side protocol security negotiation for TLS + NLA
This commit is contained in:
parent
23027a5b97
commit
baa740d612
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user