{
WLog_DBG(TAG, "Security Layer Negotiation is disabled");
/* attempt only the highest enabled protocol (see nego_attempt_*) */
-
nego->EnabledProtocols[PROTOCOL_NLA] = FALSE;
nego->EnabledProtocols[PROTOCOL_TLS] = FALSE;
nego->EnabledProtocols[PROTOCOL_RDP] = FALSE;
do
{
WLog_DBG(TAG, "state: %s", NEGO_STATE_STRINGS[nego->state]);
-
nego_send(nego);
if (nego->state == NEGO_STATE_FAIL)
{
if (freerdp_get_last_error(nego->transport->context) == FREERDP_ERROR_SUCCESS)
WLog_ERR(TAG, "Protocol Security Negotiation Failure");
+
nego->state = NEGO_STATE_FINAL;
return FALSE;
}
}
WLog_DBG(TAG, "Negotiated %s security", PROTOCOL_SECURITY_STRINGS[nego->SelectedProtocol]);
-
/* update settings with negotiated protocol security */
settings->RequestedProtocols = nego->RequestedProtocols;
settings->SelectedProtocol = nego->SelectedProtocol;
* Advertise all supported encryption methods if the client
* implementation did not set any security methods
*/
- settings->EncryptionMethods = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_56BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS;
+ settings->EncryptionMethods = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_56BIT |
+ ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS;
}
}
/* finally connect security layer (if not already done) */
if (!nego_security_connect(nego))
{
- WLog_DBG(TAG, "Failed to connect with %s security", PROTOCOL_SECURITY_STRINGS[nego->SelectedProtocol]);
+ WLog_DBG(TAG, "Failed to connect with %s security",
+ PROTOCOL_SECURITY_STRINGS[nego->SelectedProtocol]);
return FALSE;
}
* @return
*/
-BOOL nego_tcp_connect(rdpNego* nego)
+static BOOL nego_tcp_connect(rdpNego* nego)
{
if (!nego->TcpConnected)
{
BOOL nego_transport_connect(rdpNego* nego)
{
- nego_tcp_connect(nego);
+ if (!nego_tcp_connect(nego))
+ return FALSE;
if (nego->TcpConnected && !nego->NegotiateSecurityLayer)
return nego_security_connect(nego);
nego->TcpConnected = FALSE;
nego->SecurityConnected = FALSE;
-
return TRUE;
}
UINT32 cbSize;
UINT16 cchPCB = 0;
WCHAR* wszPCB = NULL;
-
WLog_DBG(TAG, "Sending preconnection PDU");
if (!nego_tcp_connect(nego))
}
s = Stream_New(NULL, cbSize);
+
if (!s)
{
WLog_ERR(TAG, "Stream_New failed!");
}
Stream_Free(s, TRUE);
-
return TRUE;
}
void nego_attempt_ext(rdpNego* nego)
{
nego->RequestedProtocols = PROTOCOL_NLA | PROTOCOL_TLS | PROTOCOL_EXT;
-
WLog_DBG(TAG, "Attempting NLA extended security");
if (!nego_transport_connect(nego))
void nego_attempt_nla(rdpNego* nego)
{
nego->RequestedProtocols = PROTOCOL_NLA | PROTOCOL_TLS;
-
WLog_DBG(TAG, "Attempting NLA security");
if (!nego_transport_connect(nego))
void nego_attempt_tls(rdpNego* nego)
{
nego->RequestedProtocols = PROTOCOL_TLS;
-
WLog_DBG(TAG, "Attempting TLS security");
if (!nego_transport_connect(nego))
void nego_attempt_rdp(rdpNego* nego)
{
nego->RequestedProtocols = PROTOCOL_RDP;
-
WLog_DBG(TAG, "Attempting RDP security");
if (!nego_transport_connect(nego))
{
int status;
wStream* s;
-
s = Stream_New(NULL, 1024);
if (!s)
}
status = nego_recv(nego->transport, s, nego);
-
Stream_Free(s, TRUE);
if (status < 0)
if (li > 6)
{
/* rdpNegData (optional) */
-
Stream_Read_UINT8(s, type); /* Type */
switch (type)
{
case TYPE_RDP_NEG_RSP:
nego_process_negotiation_response(nego, s);
-
WLog_DBG(TAG, "selected_protocol: %"PRIu32"", nego->SelectedProtocol);
/* enhanced security selected ? */
if (nego->SelectedProtocol)
{
if ((nego->SelectedProtocol == PROTOCOL_NLA) &&
- (!nego->EnabledProtocols[PROTOCOL_NLA]))
+ (!nego->EnabledProtocols[PROTOCOL_NLA]))
{
nego->state = NEGO_STATE_FAIL;
}
+
if ((nego->SelectedProtocol == PROTOCOL_TLS) &&
- (!nego->EnabledProtocols[PROTOCOL_TLS]))
+ (!nego->EnabledProtocols[PROTOCOL_TLS]))
{
nego->state = NEGO_STATE_FAIL;
}
{
nego->state = NEGO_STATE_FAIL;
}
+
break;
case TYPE_RDP_NEG_FAILURE:
* string terminated by a 0x0D0A two-byte sequence:
* Cookie:[space]mstshash=[ANSISTRING][\x0D\x0A]
*/
-
- BYTE *str = NULL;
+ BYTE* str = NULL;
UINT16 crlf = 0;
size_t pos, len;
BOOL result = FALSE;
BOOL isToken = FALSE;
-
str = Stream_Pointer(s);
pos = Stream_GetPosition(s);
while (Stream_GetRemainingLength(s) >= 2)
{
Stream_Read_UINT16(s, crlf);
+
if (crlf == 0x0A0D)
break;
+
Stream_Rewind(s, 1);
}
Stream_Rewind(s, 2);
len = Stream_GetPosition(s) - pos;
Stream_Write_UINT16(s, 0);
+
if (strlen((char*)str) == len)
{
if (isToken)
{
Stream_SetPosition(s, pos);
WLog_ERR(TAG, "invalid %s received",
- isToken ? "routing token" : "cookie");
+ isToken ? "routing token" : "cookie");
}
else
{
WLog_DBG(TAG, "received %s [%s]",
- isToken ? "routing token" : "cookie", str);
+ isToken ? "routing token" : "cookie", str);
}
return result;
if (Stream_GetRemainingLength(s) >= 8)
{
/* rdpNegData (optional) */
-
Stream_Read_UINT8(s, type); /* Type */
if (type != TYPE_RDP_NEG_REQ)
size_t bm, em;
BYTE flags = 0;
int cookie_length;
-
s = Stream_New(NULL, 512);
+
if (!s)
{
WLog_ERR(TAG, "Stream_New failed!");
/* Ensure Routing Token is correctly terminated - may already be present in string */
if ((nego->RoutingTokenLength > 2) &&
- (nego->RoutingToken[nego->RoutingTokenLength - 2] == 0x0D) &&
- (nego->RoutingToken[nego->RoutingTokenLength - 1] == 0x0A))
+ (nego->RoutingToken[nego->RoutingTokenLength - 2] == 0x0D) &&
+ (nego->RoutingToken[nego->RoutingTokenLength - 1] == 0x0A))
{
WLog_DBG(TAG, "Routing token looks correctly terminated - use verbatim");
length += nego->RoutingTokenLength;
if ((nego->RequestedProtocols > PROTOCOL_RDP) || (nego->sendNegoData))
{
/* RDP_NEG_DATA must be present for TLS and NLA */
-
if (nego->RestrictedAdminModeRequired)
flags |= RESTRICTED_ADMIN_MODE_REQUIRED;
tpkt_write_header(s, length);
tpdu_write_connection_request(s, length - 5);
Stream_SetPosition(s, em);
-
Stream_SealLength(s);
if (transport_write(nego->transport, s) < 0)
}
Stream_Free(s, TRUE);
-
return TRUE;
}
{
BYTE flags;
UINT16 length;
-
Stream_Read_UINT8(s, flags);
Stream_Read_UINT16(s, length);
Stream_Read_UINT32(s, nego->RequestedProtocols);
-
WLog_DBG(TAG, "RDP_NEG_REQ: RequestedProtocol: 0x%08"PRIX32"", nego->RequestedProtocols);
-
nego->state = NEGO_STATE_FINAL;
}
void nego_process_negotiation_response(rdpNego* nego, wStream* s)
{
UINT16 length;
-
WLog_DBG(TAG, "RDP_NEG_RSP");
if (Stream_GetRemainingLength(s) < 7)
Stream_Read_UINT8(s, nego->flags);
Stream_Read_UINT16(s, length);
Stream_Read_UINT32(s, nego->SelectedProtocol);
-
nego->state = NEGO_STATE_FINAL;
}
BYTE flags;
UINT16 length;
UINT32 failureCode;
-
WLog_DBG(TAG, "RDP_NEG_FAILURE");
-
Stream_Read_UINT8(s, flags);
Stream_Read_UINT16(s, length);
Stream_Read_UINT32(s, failureCode);
wStream* s;
BYTE flags;
rdpSettings* settings;
-
status = TRUE;
settings = nego->transport->settings;
-
s = Stream_New(NULL, 512);
+
if (!s)
{
WLog_ERR(TAG, "Stream_New failed!");
{
UINT32 errorCode = (nego->SelectedProtocol & ~PROTOCOL_FAILED_NEGO);
flags = 0;
-
Stream_Write_UINT8(s, TYPE_RDP_NEG_FAILURE);
Stream_Write_UINT8(s, flags); /* flags */
Stream_Write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */
-
Stream_Write_UINT32(s, errorCode);
length += 8;
status = FALSE;
tpkt_write_header(s, length);
tpdu_write_connection_confirm(s, length - 5);
Stream_SetPosition(s, em);
-
Stream_SealLength(s);
if (transport_write(nego->transport, s) < 0)
return NULL;
nego->transport = transport;
-
nego_init(nego);
-
return nego;
}
free(nego->RoutingToken);
nego->RoutingTokenLength = RoutingTokenLength;
nego->RoutingToken = (BYTE*) malloc(nego->RoutingTokenLength);
+
if (!nego->RoutingToken)
return FALSE;
+
CopyMemory(nego->RoutingToken, RoutingToken, nego->RoutingTokenLength);
return TRUE;
}
return TRUE;
nego->cookie = _strdup(cookie);
+
if (!nego->cookie)
return FALSE;
+
return TRUE;
}