libfreerdp-core: improve http parsing
This commit is contained in:
parent
e4f99834d0
commit
e0b0c77ecb
@ -273,7 +273,7 @@ BOOL rdp_client_connect(rdpRdp* rdp)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((rdp->nego->selected_protocol & PROTOCOL_TLS) || (rdp->nego->selected_protocol == PROTOCOL_RDP))
|
if ((rdp->nego->SelectedProtocol & PROTOCOL_TLS) || (rdp->nego->SelectedProtocol == PROTOCOL_RDP))
|
||||||
{
|
{
|
||||||
if ((settings->Username != NULL) && ((settings->Password != NULL) ||
|
if ((settings->Username != NULL) && ((settings->Password != NULL) ||
|
||||||
(settings->RedirectionPassword != NULL && settings->RedirectionPasswordLength > 0)))
|
(settings->RedirectionPassword != NULL && settings->RedirectionPasswordLength > 0)))
|
||||||
@ -973,26 +973,26 @@ BOOL rdp_server_accept_nego(rdpRdp* rdp, wStream* s)
|
|||||||
if (!nego_read_request(nego, s))
|
if (!nego_read_request(nego, s))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
nego->selected_protocol = 0;
|
nego->SelectedProtocol = 0;
|
||||||
WLog_INFO(TAG, "Client Security: NLA:%d TLS:%d RDP:%d",
|
WLog_INFO(TAG, "Client Security: NLA:%d TLS:%d RDP:%d",
|
||||||
(nego->requested_protocols & PROTOCOL_NLA) ? 1 : 0,
|
(nego->RequestedProtocols & PROTOCOL_NLA) ? 1 : 0,
|
||||||
(nego->requested_protocols & PROTOCOL_TLS) ? 1 : 0,
|
(nego->RequestedProtocols & PROTOCOL_TLS) ? 1 : 0,
|
||||||
(nego->requested_protocols == PROTOCOL_RDP) ? 1 : 0
|
(nego->RequestedProtocols == PROTOCOL_RDP) ? 1 : 0
|
||||||
);
|
);
|
||||||
WLog_INFO(TAG, "Server Security: NLA:%d TLS:%d RDP:%d",
|
WLog_INFO(TAG, "Server Security: NLA:%d TLS:%d RDP:%d",
|
||||||
settings->NlaSecurity, settings->TlsSecurity, settings->RdpSecurity);
|
settings->NlaSecurity, settings->TlsSecurity, settings->RdpSecurity);
|
||||||
|
|
||||||
if ((settings->NlaSecurity) && (nego->requested_protocols & PROTOCOL_NLA))
|
if ((settings->NlaSecurity) && (nego->RequestedProtocols & PROTOCOL_NLA))
|
||||||
{
|
{
|
||||||
nego->selected_protocol = PROTOCOL_NLA;
|
nego->SelectedProtocol = PROTOCOL_NLA;
|
||||||
}
|
}
|
||||||
else if ((settings->TlsSecurity) && (nego->requested_protocols & PROTOCOL_TLS))
|
else if ((settings->TlsSecurity) && (nego->RequestedProtocols & PROTOCOL_TLS))
|
||||||
{
|
{
|
||||||
nego->selected_protocol = PROTOCOL_TLS;
|
nego->SelectedProtocol = PROTOCOL_TLS;
|
||||||
}
|
}
|
||||||
else if ((settings->RdpSecurity) && (nego->selected_protocol == PROTOCOL_RDP))
|
else if ((settings->RdpSecurity) && (nego->SelectedProtocol == PROTOCOL_RDP))
|
||||||
{
|
{
|
||||||
nego->selected_protocol = PROTOCOL_RDP;
|
nego->SelectedProtocol = PROTOCOL_RDP;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1000,9 +1000,9 @@ BOOL rdp_server_accept_nego(rdpRdp* rdp, wStream* s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
WLog_INFO(TAG, "Negotiated Security: NLA:%d TLS:%d RDP:%d",
|
WLog_INFO(TAG, "Negotiated Security: NLA:%d TLS:%d RDP:%d",
|
||||||
(nego->selected_protocol & PROTOCOL_NLA) ? 1 : 0,
|
(nego->SelectedProtocol & PROTOCOL_NLA) ? 1 : 0,
|
||||||
(nego->selected_protocol & PROTOCOL_TLS) ? 1 : 0,
|
(nego->SelectedProtocol & PROTOCOL_TLS) ? 1 : 0,
|
||||||
(nego->selected_protocol == PROTOCOL_RDP) ? 1: 0
|
(nego->SelectedProtocol == PROTOCOL_RDP) ? 1: 0
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!nego_send_negotiation_response(nego))
|
if (!nego_send_negotiation_response(nego))
|
||||||
@ -1010,11 +1010,11 @@ BOOL rdp_server_accept_nego(rdpRdp* rdp, wStream* s)
|
|||||||
|
|
||||||
status = FALSE;
|
status = FALSE;
|
||||||
|
|
||||||
if (nego->selected_protocol & PROTOCOL_NLA)
|
if (nego->SelectedProtocol & PROTOCOL_NLA)
|
||||||
status = transport_accept_nla(rdp->transport);
|
status = transport_accept_nla(rdp->transport);
|
||||||
else if (nego->selected_protocol & PROTOCOL_TLS)
|
else if (nego->SelectedProtocol & PROTOCOL_TLS)
|
||||||
status = transport_accept_tls(rdp->transport);
|
status = transport_accept_tls(rdp->transport);
|
||||||
else if (nego->selected_protocol == PROTOCOL_RDP) /* 0 */
|
else if (nego->SelectedProtocol == PROTOCOL_RDP) /* 0 */
|
||||||
status = transport_accept_rdp(rdp->transport);
|
status = transport_accept_rdp(rdp->transport);
|
||||||
|
|
||||||
if (!status)
|
if (!status)
|
||||||
|
@ -34,6 +34,51 @@
|
|||||||
|
|
||||||
#define TAG "gateway"
|
#define TAG "gateway"
|
||||||
|
|
||||||
|
static char* string_strnstr(const char* str1, const char* str2, size_t slen)
|
||||||
|
{
|
||||||
|
char c, sc;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if ((c = *str2++) != '\0')
|
||||||
|
{
|
||||||
|
len = strlen(str2);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (slen-- < 1 || (sc = *str1++) == '\0')
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
while(sc != c);
|
||||||
|
|
||||||
|
if (len > slen)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
while(strncmp(str1, str2, len) != 0);
|
||||||
|
|
||||||
|
str1--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ((char*) str1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL strings_equals_nocase(void* obj1, void* obj2)
|
||||||
|
{
|
||||||
|
if (!obj1 || !obj2)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return _stricmp(obj1, obj2) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void string_free(void* obj1)
|
||||||
|
{
|
||||||
|
if (!obj1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
free(obj1);
|
||||||
|
}
|
||||||
|
|
||||||
HttpContext* http_context_new()
|
HttpContext* http_context_new()
|
||||||
{
|
{
|
||||||
return (HttpContext*) calloc(1, sizeof(HttpContext));
|
return (HttpContext*) calloc(1, sizeof(HttpContext));
|
||||||
@ -397,6 +442,13 @@ BOOL http_response_parse_header_field(HttpResponse* response, char* name, char*
|
|||||||
{
|
{
|
||||||
response->ContentLength = atoi(value);
|
response->ContentLength = atoi(value);
|
||||||
}
|
}
|
||||||
|
else if (_stricmp(name, "Content-Type") == 0)
|
||||||
|
{
|
||||||
|
response->ContentType = _strdup(value);
|
||||||
|
|
||||||
|
if (!response->ContentType)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
else if (_stricmp(name, "WWW-Authenticate") == 0)
|
else if (_stricmp(name, "WWW-Authenticate") == 0)
|
||||||
{
|
{
|
||||||
char* separator = NULL;
|
char* separator = NULL;
|
||||||
@ -440,6 +492,7 @@ BOOL http_response_parse_header_field(HttpResponse* response, char* name, char*
|
|||||||
|
|
||||||
BOOL http_response_parse_header(HttpResponse* response)
|
BOOL http_response_parse_header(HttpResponse* response)
|
||||||
{
|
{
|
||||||
|
char c;
|
||||||
int count;
|
int count;
|
||||||
char* line;
|
char* line;
|
||||||
char* name;
|
char* name;
|
||||||
@ -447,7 +500,6 @@ BOOL http_response_parse_header(HttpResponse* response)
|
|||||||
char* colon_pos;
|
char* colon_pos;
|
||||||
char* end_of_header;
|
char* end_of_header;
|
||||||
char end_of_header_char;
|
char end_of_header_char;
|
||||||
char c;
|
|
||||||
|
|
||||||
if (!response)
|
if (!response)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -522,22 +574,29 @@ void http_response_print(HttpResponse* response)
|
|||||||
|
|
||||||
HttpResponse* http_response_recv(rdpTls* tls)
|
HttpResponse* http_response_recv(rdpTls* tls)
|
||||||
{
|
{
|
||||||
int nbytes;
|
wStream* s;
|
||||||
int length;
|
int size;
|
||||||
|
int count;
|
||||||
int status;
|
int status;
|
||||||
BYTE* buffer;
|
int position;
|
||||||
char* content;
|
char* line;
|
||||||
char* header_end;
|
char* buffer;
|
||||||
|
char* header;
|
||||||
|
char* payload;
|
||||||
|
int bodyLength;
|
||||||
|
int payloadOffset;
|
||||||
HttpResponse* response;
|
HttpResponse* response;
|
||||||
|
|
||||||
nbytes = 0;
|
size = 1024;
|
||||||
length = 10000;
|
payload = NULL;
|
||||||
content = NULL;
|
payloadOffset = 0;
|
||||||
|
|
||||||
buffer = calloc(length, 1);
|
s = Stream_New(NULL, size);
|
||||||
|
|
||||||
if (!buffer)
|
if (!s)
|
||||||
return NULL;
|
goto out_free;
|
||||||
|
|
||||||
|
buffer = (char*) Stream_Buffer(s);
|
||||||
|
|
||||||
response = http_response_new();
|
response = http_response_new();
|
||||||
|
|
||||||
@ -548,9 +607,9 @@ HttpResponse* http_response_recv(rdpTls* tls)
|
|||||||
|
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
while (nbytes < 5)
|
while (!payloadOffset)
|
||||||
{
|
{
|
||||||
status = BIO_read(tls->bio, &buffer[nbytes], length - nbytes);
|
status = BIO_read(tls->bio, Stream_Pointer(s), Stream_Capacity(s) - Stream_GetPosition(s));
|
||||||
|
|
||||||
if (status <= 0)
|
if (status <= 0)
|
||||||
{
|
{
|
||||||
@ -564,34 +623,40 @@ HttpResponse* http_response_recv(rdpTls* tls)
|
|||||||
#ifdef HAVE_VALGRIND_MEMCHECK_H
|
#ifdef HAVE_VALGRIND_MEMCHECK_H
|
||||||
VALGRIND_MAKE_MEM_DEFINED(p, status);
|
VALGRIND_MAKE_MEM_DEFINED(p, status);
|
||||||
#endif
|
#endif
|
||||||
nbytes += status;
|
|
||||||
}
|
|
||||||
|
|
||||||
header_end = strstr((char*) buffer, "\r\n\r\n");
|
Stream_Seek(s, status);
|
||||||
|
|
||||||
if (!header_end)
|
if (Stream_GetRemainingLength(s) < 1024)
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "invalid response");
|
|
||||||
winpr_HexDump(TAG, WLOG_ERROR, buffer, status);
|
|
||||||
goto out_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
header_end += 2;
|
|
||||||
|
|
||||||
if (header_end)
|
|
||||||
{
|
|
||||||
int count;
|
|
||||||
char* line;
|
|
||||||
|
|
||||||
header_end[0] = '\0';
|
|
||||||
header_end[1] = '\0';
|
|
||||||
content = header_end + 2;
|
|
||||||
count = 0;
|
|
||||||
line = (char*) buffer;
|
|
||||||
|
|
||||||
while ((line = strstr(line, "\r\n")) != NULL)
|
|
||||||
{
|
{
|
||||||
line++;
|
Stream_EnsureRemainingCapacity(s, 1024);
|
||||||
|
buffer = (char*) Stream_Buffer(s);
|
||||||
|
payload = &buffer[payloadOffset];
|
||||||
|
}
|
||||||
|
|
||||||
|
position = Stream_GetPosition(s);
|
||||||
|
|
||||||
|
if (position >= 4)
|
||||||
|
{
|
||||||
|
line = string_strnstr(buffer, "\r\n\r\n", position);
|
||||||
|
|
||||||
|
if (line)
|
||||||
|
{
|
||||||
|
payloadOffset = (line - buffer) + 4;
|
||||||
|
payload = &buffer[payloadOffset];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (payloadOffset)
|
||||||
|
{
|
||||||
|
count = 0;
|
||||||
|
line = buffer;
|
||||||
|
|
||||||
|
position = Stream_GetPosition(s);
|
||||||
|
|
||||||
|
while ((line = string_strnstr(line, "\r\n", payloadOffset - (line - buffer) - 2)))
|
||||||
|
{
|
||||||
|
line += 2;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -605,8 +670,17 @@ HttpResponse* http_response_recv(rdpTls* tls)
|
|||||||
goto out_error;
|
goto out_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
header = (char*) malloc(payloadOffset);
|
||||||
|
|
||||||
|
if (!header)
|
||||||
|
goto out_error;
|
||||||
|
|
||||||
|
CopyMemory(header, buffer, payloadOffset);
|
||||||
|
header[payloadOffset - 1] = '\0';
|
||||||
|
header[payloadOffset - 2] = '\0';
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
line = strtok((char*) buffer, "\r\n");
|
line = strtok(header, "\r\n");
|
||||||
|
|
||||||
while (line && response->lines)
|
while (line && response->lines)
|
||||||
{
|
{
|
||||||
@ -619,10 +693,12 @@ HttpResponse* http_response_recv(rdpTls* tls)
|
|||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(header);
|
||||||
|
|
||||||
if (!http_response_parse_header(response))
|
if (!http_response_parse_header(response))
|
||||||
goto out_error;
|
goto out_error;
|
||||||
|
|
||||||
response->BodyLength = nbytes - (content - (char*) buffer);
|
response->BodyLength = Stream_GetPosition(s) - payloadOffset;
|
||||||
|
|
||||||
if (response->BodyLength > 0)
|
if (response->BodyLength > 0)
|
||||||
{
|
{
|
||||||
@ -631,44 +707,45 @@ HttpResponse* http_response_recv(rdpTls* tls)
|
|||||||
if (!response->BodyContent)
|
if (!response->BodyContent)
|
||||||
goto out_error;
|
goto out_error;
|
||||||
|
|
||||||
CopyMemory(response->BodyContent, content, response->BodyLength);
|
CopyMemory(response->BodyContent, payload, response->BodyLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
bodyLength = 0; /* expected body length */
|
||||||
|
|
||||||
|
if (response->ContentType)
|
||||||
|
{
|
||||||
|
if (_stricmp(response->ContentType, "text/plain") == 0)
|
||||||
|
{
|
||||||
|
bodyLength = response->ContentLength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bodyLength != response->BodyLength)
|
||||||
|
{
|
||||||
|
WLog_WARN(TAG, "http_response_recv: %s unexpected body length: actual: %d, expected: %d",
|
||||||
|
response->ContentType, response->ContentLength, response->BodyLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((length - nbytes) <= 0)
|
if (Stream_GetRemainingLength(s) < 1024)
|
||||||
{
|
{
|
||||||
length *= 2;
|
Stream_EnsureRemainingCapacity(s, 1024);
|
||||||
buffer = realloc(buffer, length);
|
buffer = (char*) Stream_Buffer(s);
|
||||||
|
payload = &buffer[payloadOffset];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(buffer);
|
Stream_Free(s, TRUE);
|
||||||
return response;
|
return response;
|
||||||
out_error:
|
out_error:
|
||||||
http_response_free(response);
|
http_response_free(response);
|
||||||
out_free:
|
out_free:
|
||||||
free(buffer);
|
Stream_Free(s, TRUE);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL strings_equals_nocase(void* obj1, void* obj2)
|
|
||||||
{
|
|
||||||
if (!obj1 || !obj2)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
return _stricmp(obj1, obj2) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void string_free(void* obj1)
|
|
||||||
{
|
|
||||||
if (!obj1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
free(obj1);
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpResponse* http_response_new()
|
HttpResponse* http_response_new()
|
||||||
{
|
{
|
||||||
HttpResponse* response = (HttpResponse*) calloc(1, sizeof(HttpResponse));
|
HttpResponse* response = (HttpResponse*) calloc(1, sizeof(HttpResponse));
|
||||||
@ -703,6 +780,8 @@ void http_response_free(HttpResponse* response)
|
|||||||
free(response->lines);
|
free(response->lines);
|
||||||
free(response->ReasonPhrase);
|
free(response->ReasonPhrase);
|
||||||
|
|
||||||
|
free(response->ContentType);
|
||||||
|
|
||||||
ListDictionary_Free(response->Authenticates);
|
ListDictionary_Free(response->Authenticates);
|
||||||
|
|
||||||
if (response->ContentLength > 0)
|
if (response->ContentLength > 0)
|
||||||
|
@ -83,6 +83,7 @@ struct _http_response
|
|||||||
char* ReasonPhrase;
|
char* ReasonPhrase;
|
||||||
|
|
||||||
int ContentLength;
|
int ContentLength;
|
||||||
|
char* ContentType;
|
||||||
|
|
||||||
int BodyLength;
|
int BodyLength;
|
||||||
BYTE* BodyContent;
|
BYTE* BodyContent;
|
||||||
|
@ -243,19 +243,19 @@ int rpc_ncacn_http_send_out_channel_request(rdpRpc* rpc)
|
|||||||
int rpc_ncacn_http_recv_out_channel_response(rdpRpc* rpc)
|
int rpc_ncacn_http_recv_out_channel_response(rdpRpc* rpc)
|
||||||
{
|
{
|
||||||
char* token64;
|
char* token64;
|
||||||
|
HttpResponse* response;
|
||||||
int ntlm_token_length = 0;
|
int ntlm_token_length = 0;
|
||||||
BYTE* ntlm_token_data = NULL;
|
BYTE* ntlm_token_data = NULL;
|
||||||
HttpResponse* http_response;
|
|
||||||
rdpNtlm* ntlm = rpc->NtlmHttpOut->ntlm;
|
rdpNtlm* ntlm = rpc->NtlmHttpOut->ntlm;
|
||||||
|
|
||||||
http_response = http_response_recv(rpc->TlsOut);
|
response = http_response_recv(rpc->TlsOut);
|
||||||
|
|
||||||
if (!http_response)
|
if (!response)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (ListDictionary_Contains(http_response->Authenticates, "NTLM"))
|
if (ListDictionary_Contains(response->Authenticates, "NTLM"))
|
||||||
{
|
{
|
||||||
token64 = ListDictionary_GetItemValue(http_response->Authenticates, "NTLM");
|
token64 = ListDictionary_GetItemValue(response->Authenticates, "NTLM");
|
||||||
|
|
||||||
if (!token64)
|
if (!token64)
|
||||||
goto out;
|
goto out;
|
||||||
@ -266,7 +266,7 @@ int rpc_ncacn_http_recv_out_channel_response(rdpRpc* rpc)
|
|||||||
out:
|
out:
|
||||||
ntlm->inputBuffer[0].pvBuffer = ntlm_token_data;
|
ntlm->inputBuffer[0].pvBuffer = ntlm_token_data;
|
||||||
ntlm->inputBuffer[0].cbBuffer = ntlm_token_length;
|
ntlm->inputBuffer[0].cbBuffer = ntlm_token_length;
|
||||||
http_response_free(http_response);
|
http_response_free(response);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -297,15 +297,24 @@ BOOL rpc_ntlm_http_out_connect(rdpRpc* rpc)
|
|||||||
|
|
||||||
/* Send OUT Channel Request */
|
/* Send OUT Channel Request */
|
||||||
if (rpc_ncacn_http_send_out_channel_request(rpc) <= 0)
|
if (rpc_ncacn_http_send_out_channel_request(rpc) <= 0)
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "rpc_ncacn_http_send_out_channel_request failure");
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
/* Receive OUT Channel Response */
|
/* Receive OUT Channel Response */
|
||||||
if (rpc_ncacn_http_recv_out_channel_response(rpc) <= 0)
|
if (rpc_ncacn_http_recv_out_channel_response(rpc) <= 0)
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "rpc_ncacn_http_recv_out_channel_response failure");
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
/* Send OUT Channel Request */
|
/* Send OUT Channel Request */
|
||||||
if (rpc_ncacn_http_send_out_channel_request(rpc) <= 0)
|
if (rpc_ncacn_http_send_out_channel_request(rpc) <= 0)
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "rpc_ncacn_http_send_out_channel_request failure");
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
status = TRUE;
|
status = TRUE;
|
||||||
|
|
||||||
|
@ -126,6 +126,11 @@ BOOL rts_connect(rdpRpc* rpc)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WLog_DBG(TAG, "HTTP Body (%d):", response->BodyLength);
|
||||||
|
|
||||||
|
if (response->BodyLength)
|
||||||
|
winpr_HexDump(TAG, WLOG_DEBUG, response->BodyContent, response->BodyLength);
|
||||||
|
|
||||||
http_response_free(response);
|
http_response_free(response);
|
||||||
|
|
||||||
rpc->VirtualConnection->State = VIRTUAL_CONNECTION_STATE_WAIT_A3W;
|
rpc->VirtualConnection->State = VIRTUAL_CONNECTION_STATE_WAIT_A3W;
|
||||||
|
@ -1367,7 +1367,7 @@ BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port)
|
|||||||
if (!rts_connect(rpc))
|
if (!rts_connect(rpc))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "rts_connect error!");
|
WLog_ERR(TAG, "rts_connect error!");
|
||||||
return -1;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadEvent = NULL;
|
ReadEvent = NULL;
|
||||||
|
@ -74,19 +74,19 @@ BOOL nego_connect(rdpNego* nego)
|
|||||||
|
|
||||||
if (nego->state == NEGO_STATE_INITIAL)
|
if (nego->state == NEGO_STATE_INITIAL)
|
||||||
{
|
{
|
||||||
if (nego->enabled_protocols[PROTOCOL_EXT])
|
if (nego->EnabledProtocols[PROTOCOL_EXT])
|
||||||
{
|
{
|
||||||
nego->state = NEGO_STATE_EXT;
|
nego->state = NEGO_STATE_EXT;
|
||||||
}
|
}
|
||||||
else if (nego->enabled_protocols[PROTOCOL_NLA])
|
else if (nego->EnabledProtocols[PROTOCOL_NLA])
|
||||||
{
|
{
|
||||||
nego->state = NEGO_STATE_NLA;
|
nego->state = NEGO_STATE_NLA;
|
||||||
}
|
}
|
||||||
else if (nego->enabled_protocols[PROTOCOL_TLS])
|
else if (nego->EnabledProtocols[PROTOCOL_TLS])
|
||||||
{
|
{
|
||||||
nego->state = NEGO_STATE_TLS;
|
nego->state = NEGO_STATE_TLS;
|
||||||
}
|
}
|
||||||
else if (nego->enabled_protocols[PROTOCOL_RDP])
|
else if (nego->EnabledProtocols[PROTOCOL_RDP])
|
||||||
{
|
{
|
||||||
nego->state = NEGO_STATE_RDP;
|
nego->state = NEGO_STATE_RDP;
|
||||||
}
|
}
|
||||||
@ -102,39 +102,42 @@ BOOL nego_connect(rdpNego* nego)
|
|||||||
WLog_DBG(TAG, "Security Layer Negotiation is disabled");
|
WLog_DBG(TAG, "Security Layer Negotiation is disabled");
|
||||||
/* attempt only the highest enabled protocol (see nego_attempt_*) */
|
/* attempt only the highest enabled protocol (see nego_attempt_*) */
|
||||||
|
|
||||||
nego->enabled_protocols[PROTOCOL_NLA] = FALSE;
|
nego->EnabledProtocols[PROTOCOL_NLA] = FALSE;
|
||||||
nego->enabled_protocols[PROTOCOL_TLS] = FALSE;
|
nego->EnabledProtocols[PROTOCOL_TLS] = FALSE;
|
||||||
nego->enabled_protocols[PROTOCOL_RDP] = FALSE;
|
nego->EnabledProtocols[PROTOCOL_RDP] = FALSE;
|
||||||
nego->enabled_protocols[PROTOCOL_EXT] = FALSE;
|
nego->EnabledProtocols[PROTOCOL_EXT] = FALSE;
|
||||||
|
|
||||||
if (nego->state == NEGO_STATE_EXT)
|
if (nego->state == NEGO_STATE_EXT)
|
||||||
{
|
{
|
||||||
nego->enabled_protocols[PROTOCOL_EXT] = TRUE;
|
nego->EnabledProtocols[PROTOCOL_EXT] = TRUE;
|
||||||
nego->enabled_protocols[PROTOCOL_NLA] = TRUE;
|
nego->EnabledProtocols[PROTOCOL_NLA] = TRUE;
|
||||||
nego->selected_protocol = PROTOCOL_EXT;
|
nego->SelectedProtocol = PROTOCOL_EXT;
|
||||||
}
|
}
|
||||||
else if (nego->state == NEGO_STATE_NLA)
|
else if (nego->state == NEGO_STATE_NLA)
|
||||||
{
|
{
|
||||||
nego->enabled_protocols[PROTOCOL_NLA] = TRUE;
|
nego->EnabledProtocols[PROTOCOL_NLA] = TRUE;
|
||||||
nego->selected_protocol = PROTOCOL_NLA;
|
nego->SelectedProtocol = PROTOCOL_NLA;
|
||||||
}
|
}
|
||||||
else if (nego->state == NEGO_STATE_TLS)
|
else if (nego->state == NEGO_STATE_TLS)
|
||||||
{
|
{
|
||||||
nego->enabled_protocols[PROTOCOL_TLS] = TRUE;
|
nego->EnabledProtocols[PROTOCOL_TLS] = TRUE;
|
||||||
nego->selected_protocol = PROTOCOL_TLS;
|
nego->SelectedProtocol = PROTOCOL_TLS;
|
||||||
}
|
}
|
||||||
else if (nego->state == NEGO_STATE_RDP)
|
else if (nego->state == NEGO_STATE_RDP)
|
||||||
{
|
{
|
||||||
nego->enabled_protocols[PROTOCOL_RDP] = TRUE;
|
nego->EnabledProtocols[PROTOCOL_RDP] = TRUE;
|
||||||
nego->selected_protocol = PROTOCOL_RDP;
|
nego->SelectedProtocol = PROTOCOL_RDP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!nego_send_preconnection_pdu(nego))
|
if (nego->SendPreconnectionPdu)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Failed to send preconnection pdu");
|
if (!nego_send_preconnection_pdu(nego))
|
||||||
nego->state = NEGO_STATE_FINAL;
|
{
|
||||||
return FALSE;
|
WLog_ERR(TAG, "Failed to send preconnection pdu");
|
||||||
|
nego->state = NEGO_STATE_FINAL;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,14 +156,14 @@ BOOL nego_connect(rdpNego* nego)
|
|||||||
}
|
}
|
||||||
while (nego->state != NEGO_STATE_FINAL);
|
while (nego->state != NEGO_STATE_FINAL);
|
||||||
|
|
||||||
WLog_DBG(TAG, "Negotiated %s security", PROTOCOL_SECURITY_STRINGS[nego->selected_protocol]);
|
WLog_DBG(TAG, "Negotiated %s security", PROTOCOL_SECURITY_STRINGS[nego->SelectedProtocol]);
|
||||||
|
|
||||||
/* update settings with negotiated protocol security */
|
/* update settings with negotiated protocol security */
|
||||||
settings->RequestedProtocols = nego->requested_protocols;
|
settings->RequestedProtocols = nego->RequestedProtocols;
|
||||||
settings->SelectedProtocol = nego->selected_protocol;
|
settings->SelectedProtocol = nego->SelectedProtocol;
|
||||||
settings->NegotiationFlags = nego->flags;
|
settings->NegotiationFlags = nego->flags;
|
||||||
|
|
||||||
if (nego->selected_protocol == PROTOCOL_RDP)
|
if (nego->SelectedProtocol == PROTOCOL_RDP)
|
||||||
{
|
{
|
||||||
settings->UseRdpSecurityLayer = TRUE;
|
settings->UseRdpSecurityLayer = TRUE;
|
||||||
|
|
||||||
@ -177,7 +180,7 @@ BOOL nego_connect(rdpNego* nego)
|
|||||||
/* finally connect security layer (if not already done) */
|
/* finally connect security layer (if not already done) */
|
||||||
if (!nego_security_connect(nego))
|
if (!nego_security_connect(nego))
|
||||||
{
|
{
|
||||||
WLog_DBG(TAG, "Failed to connect with %s security", PROTOCOL_SECURITY_STRINGS[nego->selected_protocol]);
|
WLog_DBG(TAG, "Failed to connect with %s security", PROTOCOL_SECURITY_STRINGS[nego->SelectedProtocol]);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,26 +199,26 @@ BOOL nego_disconnect(rdpNego* nego)
|
|||||||
/* connect to selected security layer */
|
/* connect to selected security layer */
|
||||||
BOOL nego_security_connect(rdpNego* nego)
|
BOOL nego_security_connect(rdpNego* nego)
|
||||||
{
|
{
|
||||||
if (!nego->tcp_connected)
|
if (!nego->TcpConnected)
|
||||||
{
|
{
|
||||||
nego->security_connected = FALSE;
|
nego->SecurityConnected = FALSE;
|
||||||
}
|
}
|
||||||
else if (!nego->security_connected)
|
else if (!nego->SecurityConnected)
|
||||||
{
|
{
|
||||||
if (nego->selected_protocol == PROTOCOL_NLA)
|
if (nego->SelectedProtocol == PROTOCOL_NLA)
|
||||||
{
|
{
|
||||||
WLog_DBG(TAG, "nego_security_connect with PROTOCOL_NLA");
|
WLog_DBG(TAG, "nego_security_connect with PROTOCOL_NLA");
|
||||||
nego->security_connected = transport_connect_nla(nego->transport);
|
nego->SecurityConnected = transport_connect_nla(nego->transport);
|
||||||
}
|
}
|
||||||
else if (nego->selected_protocol == PROTOCOL_TLS)
|
else if (nego->SelectedProtocol == PROTOCOL_TLS)
|
||||||
{
|
{
|
||||||
WLog_DBG(TAG, "nego_security_connect with PROTOCOL_TLS");
|
WLog_DBG(TAG, "nego_security_connect with PROTOCOL_TLS");
|
||||||
nego->security_connected = transport_connect_tls(nego->transport);
|
nego->SecurityConnected = transport_connect_tls(nego->transport);
|
||||||
}
|
}
|
||||||
else if (nego->selected_protocol == PROTOCOL_RDP)
|
else if (nego->SelectedProtocol == PROTOCOL_RDP)
|
||||||
{
|
{
|
||||||
WLog_DBG(TAG, "nego_security_connect with PROTOCOL_RDP");
|
WLog_DBG(TAG, "nego_security_connect with PROTOCOL_RDP");
|
||||||
nego->security_connected = transport_connect_rdp(nego->transport);
|
nego->SecurityConnected = transport_connect_rdp(nego->transport);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -223,7 +226,7 @@ BOOL nego_security_connect(rdpNego* nego)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nego->security_connected;
|
return nego->SecurityConnected;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -234,7 +237,7 @@ BOOL nego_security_connect(rdpNego* nego)
|
|||||||
|
|
||||||
BOOL nego_tcp_connect(rdpNego* nego)
|
BOOL nego_tcp_connect(rdpNego* nego)
|
||||||
{
|
{
|
||||||
if (!nego->tcp_connected)
|
if (!nego->TcpConnected)
|
||||||
{
|
{
|
||||||
if (nego->GatewayEnabled)
|
if (nego->GatewayEnabled)
|
||||||
{
|
{
|
||||||
@ -244,22 +247,22 @@ BOOL nego_tcp_connect(rdpNego* nego)
|
|||||||
WLog_INFO(TAG, "Detecting if host can be reached locally. - This might take some time.");
|
WLog_INFO(TAG, "Detecting if host can be reached locally. - This might take some time.");
|
||||||
WLog_INFO(TAG, "To disable auto detection use /gateway-usage-method:direct");
|
WLog_INFO(TAG, "To disable auto detection use /gateway-usage-method:direct");
|
||||||
transport_set_gateway_enabled(nego->transport, FALSE);
|
transport_set_gateway_enabled(nego->transport, FALSE);
|
||||||
nego->tcp_connected = transport_connect(nego->transport, nego->hostname, nego->port, 1);
|
nego->TcpConnected = transport_connect(nego->transport, nego->hostname, nego->port, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!nego->tcp_connected)
|
if (!nego->TcpConnected)
|
||||||
{
|
{
|
||||||
transport_set_gateway_enabled(nego->transport, TRUE);
|
transport_set_gateway_enabled(nego->transport, TRUE);
|
||||||
nego->tcp_connected = transport_connect(nego->transport, nego->hostname, nego->port, 15);
|
nego->TcpConnected = transport_connect(nego->transport, nego->hostname, nego->port, 15);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nego->tcp_connected = transport_connect(nego->transport, nego->hostname, nego->port, 15);
|
nego->TcpConnected = transport_connect(nego->transport, nego->hostname, nego->port, 15);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nego->tcp_connected;
|
return nego->TcpConnected;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -272,10 +275,10 @@ BOOL nego_transport_connect(rdpNego* nego)
|
|||||||
{
|
{
|
||||||
nego_tcp_connect(nego);
|
nego_tcp_connect(nego);
|
||||||
|
|
||||||
if (nego->tcp_connected && !nego->NegotiateSecurityLayer)
|
if (nego->TcpConnected && !nego->NegotiateSecurityLayer)
|
||||||
return nego_security_connect(nego);
|
return nego_security_connect(nego);
|
||||||
|
|
||||||
return nego->tcp_connected;
|
return nego->TcpConnected;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -286,11 +289,11 @@ BOOL nego_transport_connect(rdpNego* nego)
|
|||||||
|
|
||||||
BOOL nego_transport_disconnect(rdpNego* nego)
|
BOOL nego_transport_disconnect(rdpNego* nego)
|
||||||
{
|
{
|
||||||
if (nego->tcp_connected)
|
if (nego->TcpConnected)
|
||||||
transport_disconnect(nego->transport);
|
transport_disconnect(nego->transport);
|
||||||
|
|
||||||
nego->tcp_connected = FALSE;
|
nego->TcpConnected = FALSE;
|
||||||
nego->security_connected = FALSE;
|
nego->SecurityConnected = FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -308,9 +311,6 @@ BOOL nego_send_preconnection_pdu(rdpNego* nego)
|
|||||||
UINT16 cchPCB = 0;
|
UINT16 cchPCB = 0;
|
||||||
WCHAR* wszPCB = NULL;
|
WCHAR* wszPCB = NULL;
|
||||||
|
|
||||||
if (!nego->send_preconnection_pdu)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
WLog_DBG(TAG, "Sending preconnection PDU");
|
WLog_DBG(TAG, "Sending preconnection PDU");
|
||||||
|
|
||||||
if (!nego_tcp_connect(nego))
|
if (!nego_tcp_connect(nego))
|
||||||
@ -319,9 +319,9 @@ BOOL nego_send_preconnection_pdu(rdpNego* nego)
|
|||||||
/* it's easier to always send the version 2 PDU, and it's just 2 bytes overhead */
|
/* it's easier to always send the version 2 PDU, and it's just 2 bytes overhead */
|
||||||
cbSize = PRECONNECTION_PDU_V2_MIN_SIZE;
|
cbSize = PRECONNECTION_PDU_V2_MIN_SIZE;
|
||||||
|
|
||||||
if (nego->preconnection_blob)
|
if (nego->PreconnectionBlob)
|
||||||
{
|
{
|
||||||
cchPCB = (UINT16) ConvertToUnicode(CP_UTF8, 0, nego->preconnection_blob, -1, &wszPCB, 0);
|
cchPCB = (UINT16) ConvertToUnicode(CP_UTF8, 0, nego->PreconnectionBlob, -1, &wszPCB, 0);
|
||||||
cchPCB += 1; /* zero-termination */
|
cchPCB += 1; /* zero-termination */
|
||||||
cbSize += cchPCB * 2;
|
cbSize += cchPCB * 2;
|
||||||
}
|
}
|
||||||
@ -331,7 +331,7 @@ BOOL nego_send_preconnection_pdu(rdpNego* nego)
|
|||||||
Stream_Write_UINT32(s, cbSize); /* cbSize */
|
Stream_Write_UINT32(s, cbSize); /* cbSize */
|
||||||
Stream_Write_UINT32(s, 0); /* Flags */
|
Stream_Write_UINT32(s, 0); /* Flags */
|
||||||
Stream_Write_UINT32(s, PRECONNECTION_PDU_V2); /* Version */
|
Stream_Write_UINT32(s, PRECONNECTION_PDU_V2); /* Version */
|
||||||
Stream_Write_UINT32(s, nego->preconnection_id); /* Id */
|
Stream_Write_UINT32(s, nego->PreconnectionId); /* Id */
|
||||||
Stream_Write_UINT16(s, cchPCB); /* cchPCB */
|
Stream_Write_UINT16(s, cchPCB); /* cchPCB */
|
||||||
|
|
||||||
if (wszPCB)
|
if (wszPCB)
|
||||||
@ -360,7 +360,7 @@ BOOL nego_send_preconnection_pdu(rdpNego* nego)
|
|||||||
|
|
||||||
void nego_attempt_ext(rdpNego* nego)
|
void nego_attempt_ext(rdpNego* nego)
|
||||||
{
|
{
|
||||||
nego->requested_protocols = PROTOCOL_NLA | PROTOCOL_TLS | PROTOCOL_EXT;
|
nego->RequestedProtocols = PROTOCOL_NLA | PROTOCOL_TLS | PROTOCOL_EXT;
|
||||||
|
|
||||||
WLog_DBG(TAG, "Attempting NLA extended security");
|
WLog_DBG(TAG, "Attempting NLA extended security");
|
||||||
|
|
||||||
@ -388,11 +388,11 @@ void nego_attempt_ext(rdpNego* nego)
|
|||||||
{
|
{
|
||||||
nego_transport_disconnect(nego);
|
nego_transport_disconnect(nego);
|
||||||
|
|
||||||
if (nego->enabled_protocols[PROTOCOL_NLA])
|
if (nego->EnabledProtocols[PROTOCOL_NLA])
|
||||||
nego->state = NEGO_STATE_NLA;
|
nego->state = NEGO_STATE_NLA;
|
||||||
else if (nego->enabled_protocols[PROTOCOL_TLS])
|
else if (nego->EnabledProtocols[PROTOCOL_TLS])
|
||||||
nego->state = NEGO_STATE_TLS;
|
nego->state = NEGO_STATE_TLS;
|
||||||
else if (nego->enabled_protocols[PROTOCOL_RDP])
|
else if (nego->EnabledProtocols[PROTOCOL_RDP])
|
||||||
nego->state = NEGO_STATE_RDP;
|
nego->state = NEGO_STATE_RDP;
|
||||||
else
|
else
|
||||||
nego->state = NEGO_STATE_FAIL;
|
nego->state = NEGO_STATE_FAIL;
|
||||||
@ -406,7 +406,7 @@ void nego_attempt_ext(rdpNego* nego)
|
|||||||
|
|
||||||
void nego_attempt_nla(rdpNego* nego)
|
void nego_attempt_nla(rdpNego* nego)
|
||||||
{
|
{
|
||||||
nego->requested_protocols = PROTOCOL_NLA | PROTOCOL_TLS;
|
nego->RequestedProtocols = PROTOCOL_NLA | PROTOCOL_TLS;
|
||||||
|
|
||||||
WLog_DBG(TAG, "Attempting NLA security");
|
WLog_DBG(TAG, "Attempting NLA security");
|
||||||
|
|
||||||
@ -434,9 +434,9 @@ void nego_attempt_nla(rdpNego* nego)
|
|||||||
{
|
{
|
||||||
nego_transport_disconnect(nego);
|
nego_transport_disconnect(nego);
|
||||||
|
|
||||||
if (nego->enabled_protocols[PROTOCOL_TLS])
|
if (nego->EnabledProtocols[PROTOCOL_TLS])
|
||||||
nego->state = NEGO_STATE_TLS;
|
nego->state = NEGO_STATE_TLS;
|
||||||
else if (nego->enabled_protocols[PROTOCOL_RDP])
|
else if (nego->EnabledProtocols[PROTOCOL_RDP])
|
||||||
nego->state = NEGO_STATE_RDP;
|
nego->state = NEGO_STATE_RDP;
|
||||||
else
|
else
|
||||||
nego->state = NEGO_STATE_FAIL;
|
nego->state = NEGO_STATE_FAIL;
|
||||||
@ -450,7 +450,7 @@ void nego_attempt_nla(rdpNego* nego)
|
|||||||
|
|
||||||
void nego_attempt_tls(rdpNego* nego)
|
void nego_attempt_tls(rdpNego* nego)
|
||||||
{
|
{
|
||||||
nego->requested_protocols = PROTOCOL_TLS;
|
nego->RequestedProtocols = PROTOCOL_TLS;
|
||||||
|
|
||||||
WLog_DBG(TAG, "Attempting TLS security");
|
WLog_DBG(TAG, "Attempting TLS security");
|
||||||
|
|
||||||
@ -476,7 +476,7 @@ void nego_attempt_tls(rdpNego* nego)
|
|||||||
{
|
{
|
||||||
nego_transport_disconnect(nego);
|
nego_transport_disconnect(nego);
|
||||||
|
|
||||||
if (nego->enabled_protocols[PROTOCOL_RDP])
|
if (nego->EnabledProtocols[PROTOCOL_RDP])
|
||||||
nego->state = NEGO_STATE_RDP;
|
nego->state = NEGO_STATE_RDP;
|
||||||
else
|
else
|
||||||
nego->state = NEGO_STATE_FAIL;
|
nego->state = NEGO_STATE_FAIL;
|
||||||
@ -490,7 +490,7 @@ void nego_attempt_tls(rdpNego* nego)
|
|||||||
|
|
||||||
void nego_attempt_rdp(rdpNego* nego)
|
void nego_attempt_rdp(rdpNego* nego)
|
||||||
{
|
{
|
||||||
nego->requested_protocols = PROTOCOL_RDP;
|
nego->RequestedProtocols = PROTOCOL_RDP;
|
||||||
|
|
||||||
WLog_DBG(TAG, "Attempting RDP security");
|
WLog_DBG(TAG, "Attempting RDP security");
|
||||||
|
|
||||||
@ -580,24 +580,24 @@ int nego_recv(rdpTransport* transport, wStream* s, void* extra)
|
|||||||
case TYPE_RDP_NEG_RSP:
|
case TYPE_RDP_NEG_RSP:
|
||||||
nego_process_negotiation_response(nego, s);
|
nego_process_negotiation_response(nego, s);
|
||||||
|
|
||||||
WLog_DBG(TAG, "selected_protocol: %d", nego->selected_protocol);
|
WLog_DBG(TAG, "selected_protocol: %d", nego->SelectedProtocol);
|
||||||
|
|
||||||
/* enhanced security selected ? */
|
/* enhanced security selected ? */
|
||||||
|
|
||||||
if (nego->selected_protocol)
|
if (nego->SelectedProtocol)
|
||||||
{
|
{
|
||||||
if ((nego->selected_protocol == PROTOCOL_NLA) &&
|
if ((nego->SelectedProtocol == PROTOCOL_NLA) &&
|
||||||
(!nego->enabled_protocols[PROTOCOL_NLA]))
|
(!nego->EnabledProtocols[PROTOCOL_NLA]))
|
||||||
{
|
{
|
||||||
nego->state = NEGO_STATE_FAIL;
|
nego->state = NEGO_STATE_FAIL;
|
||||||
}
|
}
|
||||||
if ((nego->selected_protocol == PROTOCOL_TLS) &&
|
if ((nego->SelectedProtocol == PROTOCOL_TLS) &&
|
||||||
(!nego->enabled_protocols[PROTOCOL_TLS]))
|
(!nego->EnabledProtocols[PROTOCOL_TLS]))
|
||||||
{
|
{
|
||||||
nego->state = NEGO_STATE_FAIL;
|
nego->state = NEGO_STATE_FAIL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!nego->enabled_protocols[PROTOCOL_RDP])
|
else if (!nego->EnabledProtocols[PROTOCOL_RDP])
|
||||||
{
|
{
|
||||||
nego->state = NEGO_STATE_FAIL;
|
nego->state = NEGO_STATE_FAIL;
|
||||||
}
|
}
|
||||||
@ -612,7 +612,7 @@ int nego_recv(rdpTransport* transport, wStream* s, void* extra)
|
|||||||
{
|
{
|
||||||
WLog_DBG(TAG, "no rdpNegData");
|
WLog_DBG(TAG, "no rdpNegData");
|
||||||
|
|
||||||
if (!nego->enabled_protocols[PROTOCOL_RDP])
|
if (!nego->EnabledProtocols[PROTOCOL_RDP])
|
||||||
nego->state = NEGO_STATE_FAIL;
|
nego->state = NEGO_STATE_FAIL;
|
||||||
else
|
else
|
||||||
nego->state = NEGO_STATE_FINAL;
|
nego->state = NEGO_STATE_FINAL;
|
||||||
@ -645,7 +645,7 @@ BOOL nego_read_request(rdpNego* nego, wStream* s)
|
|||||||
|
|
||||||
if (li != Stream_GetRemainingLength(s) + 6)
|
if (li != Stream_GetRemainingLength(s) + 6)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Incorrect TPDU length indicator.");
|
WLog_ERR(TAG, "Incorrect TPDU length indicator.");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -677,7 +677,7 @@ BOOL nego_read_request(rdpNego* nego, wStream* s)
|
|||||||
|
|
||||||
if (type != TYPE_RDP_NEG_REQ)
|
if (type != TYPE_RDP_NEG_REQ)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Incorrect negotiation request type %d", type);
|
WLog_ERR(TAG, "Incorrect negotiation request type %d", type);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -730,8 +730,12 @@ BOOL nego_send_negotiation_request(rdpNego* nego)
|
|||||||
if (nego->RoutingToken)
|
if (nego->RoutingToken)
|
||||||
{
|
{
|
||||||
Stream_Write(s, nego->RoutingToken, nego->RoutingTokenLength);
|
Stream_Write(s, nego->RoutingToken, nego->RoutingTokenLength);
|
||||||
|
|
||||||
/* Ensure Routing Token is correctly terminated - may already be present in string */
|
/* 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))
|
|
||||||
|
if ((nego->RoutingTokenLength > 2) &&
|
||||||
|
(nego->RoutingToken[nego->RoutingTokenLength - 2] == 0x0D) &&
|
||||||
|
(nego->RoutingToken[nego->RoutingTokenLength - 1] == 0x0A))
|
||||||
{
|
{
|
||||||
WLog_DBG(TAG, "Routing token looks correctly terminated - use verbatim");
|
WLog_DBG(TAG, "Routing token looks correctly terminated - use verbatim");
|
||||||
length +=nego->RoutingTokenLength;
|
length +=nego->RoutingTokenLength;
|
||||||
@ -748,8 +752,8 @@ BOOL nego_send_negotiation_request(rdpNego* nego)
|
|||||||
{
|
{
|
||||||
cookie_length = strlen(nego->cookie);
|
cookie_length = strlen(nego->cookie);
|
||||||
|
|
||||||
if (cookie_length > (int) nego->cookie_max_length)
|
if (cookie_length > (int) nego->CookieMaxLength)
|
||||||
cookie_length = nego->cookie_max_length;
|
cookie_length = nego->CookieMaxLength;
|
||||||
|
|
||||||
Stream_Write(s, "Cookie: mstshash=", 17);
|
Stream_Write(s, "Cookie: mstshash=", 17);
|
||||||
Stream_Write(s, (BYTE*) nego->cookie, cookie_length);
|
Stream_Write(s, (BYTE*) nego->cookie, cookie_length);
|
||||||
@ -758,9 +762,9 @@ BOOL nego_send_negotiation_request(rdpNego* nego)
|
|||||||
length += cookie_length + 19;
|
length += cookie_length + 19;
|
||||||
}
|
}
|
||||||
|
|
||||||
WLog_DBG(TAG, "RequestedProtocols: %d", nego->requested_protocols);
|
WLog_DBG(TAG, "RequestedProtocols: %d", nego->RequestedProtocols);
|
||||||
|
|
||||||
if ((nego->requested_protocols > PROTOCOL_RDP) || (nego->sendNegoData))
|
if ((nego->RequestedProtocols > PROTOCOL_RDP) || (nego->sendNegoData))
|
||||||
{
|
{
|
||||||
/* RDP_NEG_DATA must be present for TLS and NLA */
|
/* RDP_NEG_DATA must be present for TLS and NLA */
|
||||||
|
|
||||||
@ -770,7 +774,7 @@ BOOL nego_send_negotiation_request(rdpNego* nego)
|
|||||||
Stream_Write_UINT8(s, TYPE_RDP_NEG_REQ);
|
Stream_Write_UINT8(s, TYPE_RDP_NEG_REQ);
|
||||||
Stream_Write_UINT8(s, flags);
|
Stream_Write_UINT8(s, flags);
|
||||||
Stream_Write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */
|
Stream_Write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */
|
||||||
Stream_Write_UINT32(s, nego->requested_protocols); /* requestedProtocols */
|
Stream_Write_UINT32(s, nego->RequestedProtocols); /* requestedProtocols */
|
||||||
length += 8;
|
length += 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -806,9 +810,9 @@ void nego_process_negotiation_request(rdpNego* nego, wStream* s)
|
|||||||
|
|
||||||
Stream_Read_UINT8(s, flags);
|
Stream_Read_UINT8(s, flags);
|
||||||
Stream_Read_UINT16(s, length);
|
Stream_Read_UINT16(s, length);
|
||||||
Stream_Read_UINT32(s, nego->requested_protocols);
|
Stream_Read_UINT32(s, nego->RequestedProtocols);
|
||||||
|
|
||||||
WLog_DBG(TAG, "RDP_NEG_REQ: RequestedProtocol: 0x%04X", nego->requested_protocols);
|
WLog_DBG(TAG, "RDP_NEG_REQ: RequestedProtocol: 0x%04X", nego->RequestedProtocols);
|
||||||
|
|
||||||
nego->state = NEGO_STATE_FINAL;
|
nego->state = NEGO_STATE_FINAL;
|
||||||
}
|
}
|
||||||
@ -834,7 +838,7 @@ void nego_process_negotiation_response(rdpNego* nego, wStream* s)
|
|||||||
|
|
||||||
Stream_Read_UINT8(s, nego->flags);
|
Stream_Read_UINT8(s, nego->flags);
|
||||||
Stream_Read_UINT16(s, length);
|
Stream_Read_UINT16(s, length);
|
||||||
Stream_Read_UINT32(s, nego->selected_protocol);
|
Stream_Read_UINT32(s, nego->SelectedProtocol);
|
||||||
|
|
||||||
nego->state = NEGO_STATE_FINAL;
|
nego->state = NEGO_STATE_FINAL;
|
||||||
}
|
}
|
||||||
@ -914,7 +918,7 @@ BOOL nego_send_negotiation_response(rdpNego* nego)
|
|||||||
bm = Stream_GetPosition(s);
|
bm = Stream_GetPosition(s);
|
||||||
Stream_Seek(s, length);
|
Stream_Seek(s, length);
|
||||||
|
|
||||||
if ((nego->selected_protocol == PROTOCOL_RDP) && !settings->RdpSecurity)
|
if ((nego->SelectedProtocol == PROTOCOL_RDP) && !settings->RdpSecurity)
|
||||||
{
|
{
|
||||||
flags = 0;
|
flags = 0;
|
||||||
|
|
||||||
@ -926,7 +930,7 @@ BOOL nego_send_negotiation_response(rdpNego* nego)
|
|||||||
* TODO: Check for other possibilities,
|
* TODO: Check for other possibilities,
|
||||||
* like SSL_NOT_ALLOWED_BY_SERVER.
|
* like SSL_NOT_ALLOWED_BY_SERVER.
|
||||||
*/
|
*/
|
||||||
WLog_ERR(TAG, "client supports only Standard RDP Security");
|
WLog_ERR(TAG, "client supports only Standard RDP Security");
|
||||||
Stream_Write_UINT32(s, SSL_REQUIRED_BY_SERVER);
|
Stream_Write_UINT32(s, SSL_REQUIRED_BY_SERVER);
|
||||||
length += 8;
|
length += 8;
|
||||||
status = FALSE;
|
status = FALSE;
|
||||||
@ -942,7 +946,7 @@ BOOL nego_send_negotiation_response(rdpNego* nego)
|
|||||||
Stream_Write_UINT8(s, TYPE_RDP_NEG_RSP);
|
Stream_Write_UINT8(s, TYPE_RDP_NEG_RSP);
|
||||||
Stream_Write_UINT8(s, flags); /* flags */
|
Stream_Write_UINT8(s, flags); /* flags */
|
||||||
Stream_Write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */
|
Stream_Write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */
|
||||||
Stream_Write_UINT32(s, nego->selected_protocol); /* selectedProtocol */
|
Stream_Write_UINT32(s, nego->SelectedProtocol); /* selectedProtocol */
|
||||||
length += 8;
|
length += 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -965,8 +969,8 @@ BOOL nego_send_negotiation_response(rdpNego* nego)
|
|||||||
if (status)
|
if (status)
|
||||||
{
|
{
|
||||||
/* update settings with negotiated protocol security */
|
/* update settings with negotiated protocol security */
|
||||||
settings->RequestedProtocols = nego->requested_protocols;
|
settings->RequestedProtocols = nego->RequestedProtocols;
|
||||||
settings->SelectedProtocol = nego->selected_protocol;
|
settings->SelectedProtocol = nego->SelectedProtocol;
|
||||||
|
|
||||||
if (settings->SelectedProtocol == PROTOCOL_RDP)
|
if (settings->SelectedProtocol == PROTOCOL_RDP)
|
||||||
{
|
{
|
||||||
@ -1032,10 +1036,10 @@ BOOL nego_send_negotiation_response(rdpNego* nego)
|
|||||||
void nego_init(rdpNego* nego)
|
void nego_init(rdpNego* nego)
|
||||||
{
|
{
|
||||||
nego->state = NEGO_STATE_INITIAL;
|
nego->state = NEGO_STATE_INITIAL;
|
||||||
nego->requested_protocols = PROTOCOL_RDP;
|
nego->RequestedProtocols = PROTOCOL_RDP;
|
||||||
nego->transport->ReceiveCallback = nego_recv;
|
nego->transport->ReceiveCallback = nego_recv;
|
||||||
nego->transport->ReceiveExtra = (void*) nego;
|
nego->transport->ReceiveExtra = (void*) nego;
|
||||||
nego->cookie_max_length = DEFAULT_COOKIE_MAX_LENGTH;
|
nego->CookieMaxLength = DEFAULT_COOKIE_MAX_LENGTH;
|
||||||
nego->sendNegoData = FALSE;
|
nego->sendNegoData = FALSE;
|
||||||
nego->flags = 0;
|
nego->flags = 0;
|
||||||
}
|
}
|
||||||
@ -1127,7 +1131,7 @@ void nego_set_gateway_bypass_local(rdpNego* nego, BOOL GatewayBypassLocal)
|
|||||||
void nego_enable_rdp(rdpNego* nego, BOOL enable_rdp)
|
void nego_enable_rdp(rdpNego* nego, BOOL enable_rdp)
|
||||||
{
|
{
|
||||||
WLog_DBG(TAG, "Enabling RDP security: %s", enable_rdp ? "TRUE" : "FALSE");
|
WLog_DBG(TAG, "Enabling RDP security: %s", enable_rdp ? "TRUE" : "FALSE");
|
||||||
nego->enabled_protocols[PROTOCOL_RDP] = enable_rdp;
|
nego->EnabledProtocols[PROTOCOL_RDP] = enable_rdp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1139,7 +1143,7 @@ void nego_enable_rdp(rdpNego* nego, BOOL enable_rdp)
|
|||||||
void nego_enable_tls(rdpNego* nego, BOOL enable_tls)
|
void nego_enable_tls(rdpNego* nego, BOOL enable_tls)
|
||||||
{
|
{
|
||||||
WLog_DBG(TAG, "Enabling TLS security: %s", enable_tls ? "TRUE" : "FALSE");
|
WLog_DBG(TAG, "Enabling TLS security: %s", enable_tls ? "TRUE" : "FALSE");
|
||||||
nego->enabled_protocols[PROTOCOL_TLS] = enable_tls;
|
nego->EnabledProtocols[PROTOCOL_TLS] = enable_tls;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1151,7 +1155,7 @@ void nego_enable_tls(rdpNego* nego, BOOL enable_tls)
|
|||||||
void nego_enable_nla(rdpNego* nego, BOOL enable_nla)
|
void nego_enable_nla(rdpNego* nego, BOOL enable_nla)
|
||||||
{
|
{
|
||||||
WLog_DBG(TAG, "Enabling NLA security: %s", enable_nla ? "TRUE" : "FALSE");
|
WLog_DBG(TAG, "Enabling NLA security: %s", enable_nla ? "TRUE" : "FALSE");
|
||||||
nego->enabled_protocols[PROTOCOL_NLA] = enable_nla;
|
nego->EnabledProtocols[PROTOCOL_NLA] = enable_nla;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1163,7 +1167,7 @@ void nego_enable_nla(rdpNego* nego, BOOL enable_nla)
|
|||||||
void nego_enable_ext(rdpNego* nego, BOOL enable_ext)
|
void nego_enable_ext(rdpNego* nego, BOOL enable_ext)
|
||||||
{
|
{
|
||||||
WLog_DBG(TAG, "Enabling NLA extended security: %s", enable_ext ? "TRUE" : "FALSE");
|
WLog_DBG(TAG, "Enabling NLA extended security: %s", enable_ext ? "TRUE" : "FALSE");
|
||||||
nego->enabled_protocols[PROTOCOL_EXT] = enable_ext;
|
nego->EnabledProtocols[PROTOCOL_EXT] = enable_ext;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1210,12 +1214,12 @@ BOOL nego_set_cookie(rdpNego* nego, char* cookie)
|
|||||||
/**
|
/**
|
||||||
* Set cookie maximum length
|
* Set cookie maximum length
|
||||||
* @param nego
|
* @param nego
|
||||||
* @param cookie_max_length
|
* @param CookieMaxLength
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void nego_set_cookie_max_length(rdpNego* nego, UINT32 cookie_max_length)
|
void nego_set_cookie_max_length(rdpNego* nego, UINT32 CookieMaxLength)
|
||||||
{
|
{
|
||||||
nego->cookie_max_length = cookie_max_length;
|
nego->CookieMaxLength = CookieMaxLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1224,9 +1228,9 @@ void nego_set_cookie_max_length(rdpNego* nego, UINT32 cookie_max_length)
|
|||||||
* @param send_pcpdu
|
* @param send_pcpdu
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void nego_set_send_preconnection_pdu(rdpNego* nego, BOOL send_pcpdu)
|
void nego_set_send_preconnection_pdu(rdpNego* nego, BOOL SendPreconnectionPdu)
|
||||||
{
|
{
|
||||||
nego->send_preconnection_pdu = send_pcpdu;
|
nego->SendPreconnectionPdu = SendPreconnectionPdu;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1235,9 +1239,9 @@ void nego_set_send_preconnection_pdu(rdpNego* nego, BOOL send_pcpdu)
|
|||||||
* @param id
|
* @param id
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void nego_set_preconnection_id(rdpNego* nego, UINT32 id)
|
void nego_set_preconnection_id(rdpNego* nego, UINT32 PreconnectionId)
|
||||||
{
|
{
|
||||||
nego->preconnection_id = id;
|
nego->PreconnectionId = PreconnectionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1246,7 +1250,7 @@ void nego_set_preconnection_id(rdpNego* nego, UINT32 id)
|
|||||||
* @param blob
|
* @param blob
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void nego_set_preconnection_blob(rdpNego* nego, char* blob)
|
void nego_set_preconnection_blob(rdpNego* nego, char* PreconnectionBlob)
|
||||||
{
|
{
|
||||||
nego->preconnection_blob = blob;
|
nego->PreconnectionBlob = PreconnectionBlob;
|
||||||
}
|
}
|
||||||
|
@ -95,20 +95,20 @@ struct rdp_nego
|
|||||||
char* cookie;
|
char* cookie;
|
||||||
BYTE* RoutingToken;
|
BYTE* RoutingToken;
|
||||||
DWORD RoutingTokenLength;
|
DWORD RoutingTokenLength;
|
||||||
BOOL send_preconnection_pdu;
|
BOOL SendPreconnectionPdu;
|
||||||
UINT32 preconnection_id;
|
UINT32 PreconnectionId;
|
||||||
char* preconnection_blob;
|
char* PreconnectionBlob;
|
||||||
|
|
||||||
NEGO_STATE state;
|
NEGO_STATE state;
|
||||||
BOOL tcp_connected;
|
BOOL TcpConnected;
|
||||||
BOOL security_connected;
|
BOOL SecurityConnected;
|
||||||
UINT32 cookie_max_length;
|
UINT32 CookieMaxLength;
|
||||||
|
|
||||||
BOOL sendNegoData;
|
BOOL sendNegoData;
|
||||||
UINT32 selected_protocol;
|
UINT32 SelectedProtocol;
|
||||||
UINT32 requested_protocols;
|
UINT32 RequestedProtocols;
|
||||||
BOOL NegotiateSecurityLayer;
|
BOOL NegotiateSecurityLayer;
|
||||||
BYTE enabled_protocols[16];
|
BYTE EnabledProtocols[16];
|
||||||
BOOL RestrictedAdminModeRequired;
|
BOOL RestrictedAdminModeRequired;
|
||||||
BOOL GatewayEnabled;
|
BOOL GatewayEnabled;
|
||||||
BOOL GatewayBypassLocal;
|
BOOL GatewayBypassLocal;
|
||||||
@ -143,7 +143,7 @@ void nego_free(rdpNego* nego);
|
|||||||
|
|
||||||
void nego_init(rdpNego* nego);
|
void nego_init(rdpNego* nego);
|
||||||
void nego_set_target(rdpNego* nego, char* hostname, int port);
|
void nego_set_target(rdpNego* nego, char* hostname, int port);
|
||||||
void nego_set_negotiation_enabled(rdpNego* nego, BOOL NegotiateSecurityLayer_enabled);
|
void nego_set_negotiation_enabled(rdpNego* nego, BOOL NegotiateSecurityLayer);
|
||||||
void nego_set_restricted_admin_mode_required(rdpNego* nego, BOOL RestrictedAdminModeRequired);
|
void nego_set_restricted_admin_mode_required(rdpNego* nego, BOOL RestrictedAdminModeRequired);
|
||||||
void nego_set_gateway_enabled(rdpNego* nego, BOOL GatewayEnabled);
|
void nego_set_gateway_enabled(rdpNego* nego, BOOL GatewayEnabled);
|
||||||
void nego_set_gateway_bypass_local(rdpNego* nego, BOOL GatewayBypassLocal);
|
void nego_set_gateway_bypass_local(rdpNego* nego, BOOL GatewayBypassLocal);
|
||||||
@ -153,9 +153,9 @@ void nego_enable_nla(rdpNego* nego, BOOL enable_nla);
|
|||||||
void nego_enable_ext(rdpNego* nego, BOOL enable_ext);
|
void nego_enable_ext(rdpNego* nego, BOOL enable_ext);
|
||||||
BOOL nego_set_routing_token(rdpNego* nego, BYTE* RoutingToken, DWORD RoutingTokenLength);
|
BOOL nego_set_routing_token(rdpNego* nego, BYTE* RoutingToken, DWORD RoutingTokenLength);
|
||||||
BOOL nego_set_cookie(rdpNego* nego, char* cookie);
|
BOOL nego_set_cookie(rdpNego* nego, char* cookie);
|
||||||
void nego_set_cookie_max_length(rdpNego* nego, UINT32 cookie_max_length);
|
void nego_set_cookie_max_length(rdpNego* nego, UINT32 CookieMaxLength);
|
||||||
void nego_set_send_preconnection_pdu(rdpNego* nego, BOOL send_pcpdu);
|
void nego_set_send_preconnection_pdu(rdpNego* nego, BOOL SendPreconnectionPdu);
|
||||||
void nego_set_preconnection_id(rdpNego* nego, UINT32 id);
|
void nego_set_preconnection_id(rdpNego* nego, UINT32 PreconnectionId);
|
||||||
void nego_set_preconnection_blob(rdpNego* nego, char* blob);
|
void nego_set_preconnection_blob(rdpNego* nego, char* PreconnectionBlob);
|
||||||
|
|
||||||
#endif /* __NEGO_H */
|
#endif /* __NEGO_H */
|
||||||
|
@ -251,7 +251,6 @@ int credssp_client_authenticate(rdpCredssp* credssp)
|
|||||||
BOOL have_context;
|
BOOL have_context;
|
||||||
BOOL have_input_buffer;
|
BOOL have_input_buffer;
|
||||||
BOOL have_pub_key_auth;
|
BOOL have_pub_key_auth;
|
||||||
sspi_GlobalInit();
|
|
||||||
|
|
||||||
if (credssp_ntlm_client_init(credssp) == 0)
|
if (credssp_ntlm_client_init(credssp) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
@ -423,7 +422,6 @@ int credssp_server_authenticate(rdpCredssp* credssp)
|
|||||||
BOOL have_context;
|
BOOL have_context;
|
||||||
BOOL have_input_buffer;
|
BOOL have_input_buffer;
|
||||||
BOOL have_pub_key_auth;
|
BOOL have_pub_key_auth;
|
||||||
sspi_GlobalInit();
|
|
||||||
|
|
||||||
if (credssp_ntlm_server_init(credssp) == 0)
|
if (credssp_ntlm_server_init(credssp) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
@ -846,7 +844,9 @@ void credssp_read_ts_credentials(rdpCredssp* credssp, PSecBuffer ts_credentials)
|
|||||||
wStream* s;
|
wStream* s;
|
||||||
int length;
|
int length;
|
||||||
int ts_password_creds_length;
|
int ts_password_creds_length;
|
||||||
|
|
||||||
s = Stream_New(ts_credentials->pvBuffer, ts_credentials->cbBuffer);
|
s = Stream_New(ts_credentials->pvBuffer, ts_credentials->cbBuffer);
|
||||||
|
|
||||||
/* TSCredentials (SEQUENCE) */
|
/* TSCredentials (SEQUENCE) */
|
||||||
ber_read_sequence_tag(s, &length);
|
ber_read_sequence_tag(s, &length);
|
||||||
/* [0] credType (INTEGER) */
|
/* [0] credType (INTEGER) */
|
||||||
@ -855,7 +855,9 @@ void credssp_read_ts_credentials(rdpCredssp* credssp, PSecBuffer ts_credentials)
|
|||||||
/* [1] credentials (OCTET STRING) */
|
/* [1] credentials (OCTET STRING) */
|
||||||
ber_read_contextual_tag(s, 1, &length, TRUE);
|
ber_read_contextual_tag(s, 1, &length, TRUE);
|
||||||
ber_read_octet_string_tag(s, &ts_password_creds_length);
|
ber_read_octet_string_tag(s, &ts_password_creds_length);
|
||||||
|
|
||||||
credssp_read_ts_password_creds(credssp, s);
|
credssp_read_ts_password_creds(credssp, s);
|
||||||
|
|
||||||
Stream_Free(s, FALSE);
|
Stream_Free(s, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -889,6 +891,7 @@ void credssp_encode_ts_credentials(rdpCredssp* credssp)
|
|||||||
int DomainLength;
|
int DomainLength;
|
||||||
int UserLength;
|
int UserLength;
|
||||||
int PasswordLength;
|
int PasswordLength;
|
||||||
|
|
||||||
DomainLength = credssp->identity.DomainLength;
|
DomainLength = credssp->identity.DomainLength;
|
||||||
UserLength = credssp->identity.UserLength;
|
UserLength = credssp->identity.UserLength;
|
||||||
PasswordLength = credssp->identity.PasswordLength;
|
PasswordLength = credssp->identity.PasswordLength;
|
||||||
@ -920,7 +923,9 @@ SECURITY_STATUS credssp_encrypt_ts_credentials(rdpCredssp* credssp)
|
|||||||
SecBuffer Buffers[2];
|
SecBuffer Buffers[2];
|
||||||
SecBufferDesc Message;
|
SecBufferDesc Message;
|
||||||
SECURITY_STATUS status;
|
SECURITY_STATUS status;
|
||||||
|
|
||||||
credssp_encode_ts_credentials(credssp);
|
credssp_encode_ts_credentials(credssp);
|
||||||
|
|
||||||
Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */
|
Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */
|
||||||
Buffers[1].BufferType = SECBUFFER_DATA; /* TSCredentials */
|
Buffers[1].BufferType = SECBUFFER_DATA; /* TSCredentials */
|
||||||
sspi_SecBufferAlloc(&credssp->authInfo, credssp->ContextSizes.cbMaxSignature + credssp->ts_credentials.cbBuffer);
|
sspi_SecBufferAlloc(&credssp->authInfo, credssp->ContextSizes.cbMaxSignature + credssp->ts_credentials.cbBuffer);
|
||||||
@ -930,9 +935,11 @@ SECURITY_STATUS credssp_encrypt_ts_credentials(rdpCredssp* credssp)
|
|||||||
Buffers[1].cbBuffer = credssp->ts_credentials.cbBuffer;
|
Buffers[1].cbBuffer = credssp->ts_credentials.cbBuffer;
|
||||||
Buffers[1].pvBuffer = &((BYTE*) credssp->authInfo.pvBuffer)[Buffers[0].cbBuffer];
|
Buffers[1].pvBuffer = &((BYTE*) credssp->authInfo.pvBuffer)[Buffers[0].cbBuffer];
|
||||||
CopyMemory(Buffers[1].pvBuffer, credssp->ts_credentials.pvBuffer, Buffers[1].cbBuffer);
|
CopyMemory(Buffers[1].pvBuffer, credssp->ts_credentials.pvBuffer, Buffers[1].cbBuffer);
|
||||||
|
|
||||||
Message.cBuffers = 2;
|
Message.cBuffers = 2;
|
||||||
Message.ulVersion = SECBUFFER_VERSION;
|
Message.ulVersion = SECBUFFER_VERSION;
|
||||||
Message.pBuffers = (PSecBuffer) &Buffers;
|
Message.pBuffers = (PSecBuffer) &Buffers;
|
||||||
|
|
||||||
status = credssp->table->EncryptMessage(&credssp->context, 0, &Message, credssp->send_seq_num++);
|
status = credssp->table->EncryptMessage(&credssp->context, 0, &Message, credssp->send_seq_num++);
|
||||||
|
|
||||||
if (status != SEC_E_OK)
|
if (status != SEC_E_OK)
|
||||||
@ -1084,7 +1091,9 @@ int credssp_recv(rdpCredssp* credssp)
|
|||||||
int length;
|
int length;
|
||||||
int status;
|
int status;
|
||||||
UINT32 version;
|
UINT32 version;
|
||||||
|
|
||||||
s = Stream_New(NULL, 4096);
|
s = Stream_New(NULL, 4096);
|
||||||
|
|
||||||
status = transport_read_pdu(credssp->transport, s);
|
status = transport_read_pdu(credssp->transport, s);
|
||||||
|
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
|
@ -451,7 +451,7 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra)
|
|||||||
if (!rdp_server_accept_nego(rdp, s))
|
if (!rdp_server_accept_nego(rdp, s))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (rdp->nego->selected_protocol & PROTOCOL_NLA)
|
if (rdp->nego->SelectedProtocol & PROTOCOL_NLA)
|
||||||
{
|
{
|
||||||
sspi_CopyAuthIdentity(&client->identity, &(rdp->nego->transport->credssp->identity));
|
sspi_CopyAuthIdentity(&client->identity, &(rdp->nego->transport->credssp->identity));
|
||||||
IFCALLRET(client->Logon, client->authenticated, client, &client->identity, TRUE);
|
IFCALLRET(client->Logon, client->authenticated, client, &client->identity, TRUE);
|
||||||
|
Loading…
Reference in New Issue
Block a user