libfreerdp-core: improve reconnection

This commit is contained in:
Marc-André Moreau 2015-02-06 14:21:26 -05:00
parent 82d58086db
commit fa06c4d401
13 changed files with 253 additions and 151 deletions

View File

@ -553,7 +553,7 @@ int drdynvc_send(drdynvcPlugin* drdynvc, wStream* s)
if (status != CHANNEL_RC_OK) if (status != CHANNEL_RC_OK)
{ {
Stream_Free(s, TRUE); Stream_Free(s, TRUE);
WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]",
WTSErrorToString(status), status); WTSErrorToString(status), status);
} }
@ -643,7 +643,7 @@ int drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, BYTE* data, UIN
if (status != CHANNEL_RC_OK) if (status != CHANNEL_RC_OK)
{ {
drdynvc->channel_error = status; drdynvc->channel_error = status;
WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]",
WTSErrorToString(status), status); WTSErrorToString(status), status);
return 1; return 1;
} }
@ -664,7 +664,7 @@ static int drdynvc_send_capability_response(drdynvcPlugin* drdynvc)
if (status != CHANNEL_RC_OK) if (status != CHANNEL_RC_OK)
{ {
WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]",
WTSErrorToString(status), status); WTSErrorToString(status), status);
return 1; return 1;
} }
@ -771,7 +771,7 @@ static int drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, int cb
if (status != CHANNEL_RC_OK) if (status != CHANNEL_RC_OK)
{ {
WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]",
WTSErrorToString(status), status); WTSErrorToString(status), status);
return 1; return 1;
} }
@ -835,7 +835,7 @@ static int drdynvc_process_close_request(drdynvcPlugin* drdynvc, int Sp, int cbC
if (error != CHANNEL_RC_OK) if (error != CHANNEL_RC_OK)
{ {
WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]",
WTSErrorToString(error), error); WTSErrorToString(error), error);
return 1; return 1;
} }
@ -973,7 +973,7 @@ static void drdynvc_virtual_channel_event_data_received(drdynvcPlugin* drdynvc,
{ {
if (Stream_Capacity(data_in) != Stream_GetPosition(data_in)) if (Stream_Capacity(data_in) != Stream_GetPosition(data_in))
{ {
WLog_ERR(TAG, "drdynvc_plugin_process_received: read error"); WLog_ERR(TAG, "drdynvc_plugin_process_received: read error");
} }
drdynvc->data_in = NULL; drdynvc->data_in = NULL;
@ -993,7 +993,7 @@ static VOID VCAPITYPE drdynvc_virtual_channel_open_event(DWORD openHandle, UINT
if (!drdynvc) if (!drdynvc)
{ {
WLog_ERR(TAG, "drdynvc_virtual_channel_open_event: error no match"); WLog_ERR(TAG, "drdynvc_virtual_channel_open_event: error no match");
return; return;
} }
@ -1055,7 +1055,7 @@ static void drdynvc_virtual_channel_event_connected(drdynvcPlugin* drdynvc, LPVO
if (status != CHANNEL_RC_OK) if (status != CHANNEL_RC_OK)
{ {
WLog_ERR(TAG, "pVirtualChannelOpen failed with %s [%08X]", WLog_ERR(TAG, "pVirtualChannelOpen failed with %s [%08X]",
WTSErrorToString(status), status); WTSErrorToString(status), status);
return; return;
} }
@ -1130,7 +1130,7 @@ static VOID VCAPITYPE drdynvc_virtual_channel_init_event(LPVOID pInitHandle, UIN
if (!drdynvc) if (!drdynvc)
{ {
WLog_ERR(TAG, "drdynvc_virtual_channel_init_event: error no match"); WLog_ERR(TAG, "drdynvc_virtual_channel_init_event: error no match");
return; return;
} }

View File

@ -132,8 +132,7 @@ COMMAND_LINE_ARGUMENT_A args[] =
{ "sec-tls", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "tls protocol security" }, { "sec-tls", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "tls protocol security" },
{ "sec-nla", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "nla protocol security" }, { "sec-nla", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "nla protocol security" },
{ "sec-ext", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "nla extended protocol security" }, { "sec-ext", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "nla extended protocol security" },
{ "tls-ciphers", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "List of permitted openssl ciphers - see ciphers(1)" }, { "tls-ciphers", COMMAND_LINE_VALUE_REQUIRED, "<netmon|ma|ciphers>", NULL, NULL, -1, NULL, "Allowed TLS ciphers" },
{ "tls-ciphers-netmon", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "Use tls ciphers that netmon can parse" },
{ "cert-name", COMMAND_LINE_VALUE_REQUIRED, "<name>", NULL, NULL, -1, NULL, "certificate name" }, { "cert-name", COMMAND_LINE_VALUE_REQUIRED, "<name>", NULL, NULL, -1, NULL, "certificate name" },
{ "cert-ignore", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "ignore certificate" }, { "cert-ignore", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "ignore certificate" },
{ "pcb", COMMAND_LINE_VALUE_REQUIRED, "<blob>", NULL, NULL, -1, NULL, "Preconnection Blob" }, { "pcb", COMMAND_LINE_VALUE_REQUIRED, "<blob>", NULL, NULL, -1, NULL, "Preconnection Blob" },
@ -1810,11 +1809,18 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
} }
CommandLineSwitchCase(arg, "tls-ciphers") CommandLineSwitchCase(arg, "tls-ciphers")
{ {
settings->PermittedTLSCiphers = _strdup(arg->Value); if (strcmp(arg->Value, "netmon") == 0)
} {
CommandLineSwitchCase(arg, "tls-ciphers-netmon") settings->AllowedTlsCiphers = _strdup("ALL:!ECDH");
{ }
settings->PermittedTLSCiphers = arg->Value ? _strdup("ALL:!ECDH") : NULL; else if (strcmp(arg->Value, "ma") == 0)
{
settings->AllowedTlsCiphers = _strdup("AES128-SHA");
}
else
{
settings->AllowedTlsCiphers = _strdup(arg->Value);
}
} }
CommandLineSwitchCase(arg, "cert-name") CommandLineSwitchCase(arg, "cert-name")
{ {

View File

@ -615,6 +615,7 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL;
#define FreeRDP_AuthenticationServiceClass 1098 #define FreeRDP_AuthenticationServiceClass 1098
#define FreeRDP_DisableCredentialsDelegation 1099 #define FreeRDP_DisableCredentialsDelegation 1099
#define FreeRDP_AuthenticationLevel 1100 #define FreeRDP_AuthenticationLevel 1100
#define FreeRDP_AllowedTlsCiphers 1101
#define FreeRDP_MstscCookieMode 1152 #define FreeRDP_MstscCookieMode 1152
#define FreeRDP_CookieMaxLength 1153 #define FreeRDP_CookieMaxLength 1153
#define FreeRDP_PreconnectionId 1154 #define FreeRDP_PreconnectionId 1154
@ -998,7 +999,7 @@ struct rdp_settings
ALIGN64 char* AuthenticationServiceClass; /* 1098 */ ALIGN64 char* AuthenticationServiceClass; /* 1098 */
ALIGN64 BOOL DisableCredentialsDelegation; /* 1099 */ ALIGN64 BOOL DisableCredentialsDelegation; /* 1099 */
ALIGN64 BOOL AuthenticationLevel; /* 1100 */ ALIGN64 BOOL AuthenticationLevel; /* 1100 */
ALIGN64 char* PermittedTLSCiphers; /* 1101 */ ALIGN64 char* AllowedTlsCiphers; /* 1101 */
UINT64 padding1152[1152 - 1102]; /* 1102 */ UINT64 padding1152[1152 - 1102]; /* 1102 */
/* Connection Cookie */ /* Connection Cookie */

View File

@ -773,6 +773,49 @@ void key_free(rdpRsaKey* key)
free(key); free(key);
} }
rdpCertificate* certificate_clone(rdpCertificate* certificate)
{
int index;
rdpCertificate* _certificate = (rdpCertificate*) calloc(1, sizeof(rdpCertificate));
if (!_certificate)
return NULL;
CopyMemory(_certificate, certificate, sizeof(rdpCertificate));
if (certificate->cert_info.ModulusLength)
{
_certificate->cert_info.Modulus = (BYTE*) malloc(certificate->cert_info.ModulusLength);
CopyMemory(_certificate->cert_info.Modulus, certificate->cert_info.Modulus, certificate->cert_info.ModulusLength);
_certificate->cert_info.ModulusLength = certificate->cert_info.ModulusLength;
}
if (certificate->x509_cert_chain)
{
_certificate->x509_cert_chain = (rdpX509CertChain*) malloc(sizeof(rdpX509CertChain));
CopyMemory(_certificate->x509_cert_chain, certificate->x509_cert_chain, sizeof(rdpX509CertChain));
if (certificate->x509_cert_chain->count)
{
_certificate->x509_cert_chain->array = (rdpCertBlob*) calloc(certificate->x509_cert_chain->count, sizeof(rdpCertBlob));
for (index = 0; index < certificate->x509_cert_chain->count; index++)
{
_certificate->x509_cert_chain->array[index].length = certificate->x509_cert_chain->array[index].length;
if (certificate->x509_cert_chain->array[index].length)
{
_certificate->x509_cert_chain->array[index].data = (BYTE*) malloc(certificate->x509_cert_chain->array[index].length);
CopyMemory(_certificate->x509_cert_chain->array[index].data, certificate->x509_cert_chain->array[index].data,
_certificate->x509_cert_chain->array[index].length);
}
}
}
}
return _certificate;
}
/** /**
* Instantiate new certificate module.\n * Instantiate new certificate module.\n
* @param rdp RDP module * @param rdp RDP module

View File

@ -53,6 +53,8 @@ BOOL certificate_read_server_proprietary_certificate(rdpCertificate* certificate
BOOL certificate_read_server_x509_certificate_chain(rdpCertificate* certificate, wStream* s); BOOL certificate_read_server_x509_certificate_chain(rdpCertificate* certificate, wStream* s);
BOOL certificate_read_server_certificate(rdpCertificate* certificate, BYTE* server_cert, int length); BOOL certificate_read_server_certificate(rdpCertificate* certificate, BYTE* server_cert, int length);
rdpCertificate* certificate_clone(rdpCertificate* certificate);
rdpCertificate* certificate_new(void); rdpCertificate* certificate_new(void);
void certificate_free(rdpCertificate* certificate); void certificate_free(rdpCertificate* certificate);

View File

@ -172,7 +172,7 @@
BOOL rdp_client_connect(rdpRdp* rdp) BOOL rdp_client_connect(rdpRdp* rdp)
{ {
BOOL ret; BOOL status;
rdpSettings* settings = rdp->settings; rdpSettings* settings = rdp->settings;
if (rdp->settingsCopy) if (rdp->settingsCopy)
@ -213,6 +213,7 @@ BOOL rdp_client_connect(rdpRdp* rdp)
cookie_length = domain_length + 1 + user_length; cookie_length = domain_length + 1 + user_length;
cookie = (char*) malloc(cookie_length + 1); cookie = (char*) malloc(cookie_length + 1);
if (!cookie) if (!cookie)
return FALSE; return FALSE;
@ -225,15 +226,15 @@ BOOL rdp_client_connect(rdpRdp* rdp)
cookie[cookie_length] = '\0'; cookie[cookie_length] = '\0';
ret = nego_set_cookie(rdp->nego, cookie); status = nego_set_cookie(rdp->nego, cookie);
free(cookie); free(cookie);
} }
else else
{ {
ret = nego_set_cookie(rdp->nego, settings->Username); status = nego_set_cookie(rdp->nego, settings->Username);
} }
if (!ret) if (!status)
return FALSE; return FALSE;
nego_set_send_preconnection_pdu(rdp->nego, settings->SendPreconnectionPdu); nego_set_send_preconnection_pdu(rdp->nego, settings->SendPreconnectionPdu);
@ -269,7 +270,7 @@ BOOL rdp_client_connect(rdpRdp* rdp)
freerdp_set_last_error(rdp->context, FREERDP_ERROR_SECURITY_NEGO_CONNECT_FAILED); freerdp_set_last_error(rdp->context, FREERDP_ERROR_SECURITY_NEGO_CONNECT_FAILED);
} }
WLog_ERR(TAG, "Error: protocol security negotiation or connection failure"); WLog_ERR(TAG, "Error: protocol security negotiation or connection failure");
return FALSE; return FALSE;
} }
@ -297,7 +298,7 @@ BOOL rdp_client_connect(rdpRdp* rdp)
freerdp_set_last_error(rdp->context, FREERDP_ERROR_MCS_CONNECT_INITIAL_ERROR); freerdp_set_last_error(rdp->context, FREERDP_ERROR_MCS_CONNECT_INITIAL_ERROR);
} }
WLog_ERR(TAG, "Error: unable to send MCS Connect Initial"); WLog_ERR(TAG, "Error: unable to send MCS Connect Initial");
return FALSE; return FALSE;
} }
@ -319,7 +320,7 @@ BOOL rdp_client_connect(rdpRdp* rdp)
BOOL rdp_client_disconnect(rdpRdp* rdp) BOOL rdp_client_disconnect(rdpRdp* rdp)
{ {
BOOL rc; BOOL status;
if (rdp->settingsCopy) if (rdp->settingsCopy)
{ {
@ -327,10 +328,13 @@ BOOL rdp_client_disconnect(rdpRdp* rdp)
rdp->settingsCopy = NULL; rdp->settingsCopy = NULL;
} }
rc = nego_disconnect(rdp->nego); status = nego_disconnect(rdp->nego);
rdp_reset(rdp); rdp_reset(rdp);
rdp_client_transition_to_state(rdp, CONNECTION_STATE_INITIAL); rdp_client_transition_to_state(rdp, CONNECTION_STATE_INITIAL);
return rc;
return status;
} }
BOOL rdp_client_redirect(rdpRdp* rdp) BOOL rdp_client_redirect(rdpRdp* rdp)
@ -381,6 +385,17 @@ BOOL rdp_client_redirect(rdpRdp* rdp)
return status; return status;
} }
BOOL rdp_client_reconnect(rdpRdp* rdp)
{
BOOL status;
rdp_client_disconnect(rdp);
status = rdp_client_connect(rdp);
return status;
}
static BYTE fips_ivec[8] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF }; static BYTE fips_ivec[8] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
static BOOL rdp_client_establish_keys(rdpRdp* rdp) static BOOL rdp_client_establish_keys(rdpRdp* rdp)
@ -631,7 +646,7 @@ BOOL rdp_client_connect_mcs_connect_response(rdpRdp* rdp, wStream* s)
{ {
if (!mcs_recv_connect_response(rdp->mcs, s)) if (!mcs_recv_connect_response(rdp->mcs, s))
{ {
WLog_ERR(TAG, "rdp_client_connect_mcs_connect_response: mcs_recv_connect_response failed"); WLog_ERR(TAG, "rdp_client_connect_mcs_connect_response: mcs_recv_connect_response failed");
return FALSE; return FALSE;
} }
@ -795,7 +810,7 @@ int rdp_client_connect_license(rdpRdp* rdp, wStream* s)
if (rdp->license->state == LICENSE_STATE_ABORTED) if (rdp->license->state == LICENSE_STATE_ABORTED)
{ {
WLog_ERR(TAG, "license connection sequence aborted."); WLog_ERR(TAG, "license connection sequence aborted.");
return -1; return -1;
} }
@ -974,12 +989,12 @@ BOOL rdp_server_accept_nego(rdpRdp* rdp, wStream* s)
return FALSE; return FALSE;
nego->SelectedProtocol = 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->RequestedProtocols & PROTOCOL_NLA) ? 1 : 0, (nego->RequestedProtocols & PROTOCOL_NLA) ? 1 : 0,
(nego->RequestedProtocols & PROTOCOL_TLS) ? 1 : 0, (nego->RequestedProtocols & PROTOCOL_TLS) ? 1 : 0,
(nego->RequestedProtocols == 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->RequestedProtocols & PROTOCOL_NLA)) if ((settings->NlaSecurity) && (nego->RequestedProtocols & PROTOCOL_NLA))
@ -996,10 +1011,10 @@ BOOL rdp_server_accept_nego(rdpRdp* rdp, wStream* s)
} }
else else
{ {
WLog_ERR(TAG, "Protocol security negotiation failure"); WLog_ERR(TAG, "Protocol security negotiation failure");
} }
WLog_INFO(TAG, "Negotiated Security: NLA:%d TLS:%d RDP:%d", WLog_INFO(TAG, "Negotiated Security: NLA:%d TLS:%d RDP:%d",
(nego->SelectedProtocol & PROTOCOL_NLA) ? 1 : 0, (nego->SelectedProtocol & PROTOCOL_NLA) ? 1 : 0,
(nego->SelectedProtocol & PROTOCOL_TLS) ? 1 : 0, (nego->SelectedProtocol & PROTOCOL_TLS) ? 1 : 0,
(nego->SelectedProtocol == PROTOCOL_RDP) ? 1: 0 (nego->SelectedProtocol == PROTOCOL_RDP) ? 1: 0
@ -1035,12 +1050,12 @@ BOOL rdp_server_accept_mcs_connect_initial(rdpRdp* rdp, wStream* s)
if (!mcs_recv_connect_initial(mcs, s)) if (!mcs_recv_connect_initial(mcs, s))
return FALSE; return FALSE;
WLog_INFO(TAG, "Accepted client: %s", rdp->settings->ClientHostname); WLog_INFO(TAG, "Accepted client: %s", rdp->settings->ClientHostname);
WLog_INFO(TAG, "Accepted channels:"); WLog_INFO(TAG, "Accepted channels:");
for (i = 0; i < mcs->channelCount; i++) for (i = 0; i < mcs->channelCount; i++)
{ {
WLog_INFO(TAG, " %s", mcs->channels[i].Name); WLog_INFO(TAG, " %s", mcs->channels[i].Name);
} }
if (!mcs_send_connect_response(mcs)) if (!mcs_send_connect_response(mcs))

View File

@ -49,6 +49,7 @@ enum CONNECTION_STATE
BOOL rdp_client_connect(rdpRdp* rdp); BOOL rdp_client_connect(rdpRdp* rdp);
BOOL rdp_client_disconnect(rdpRdp* rdp); BOOL rdp_client_disconnect(rdpRdp* rdp);
BOOL rdp_client_reconnect(rdpRdp* rdp);
BOOL rdp_client_redirect(rdpRdp* rdp); BOOL rdp_client_redirect(rdpRdp* rdp);
BOOL rdp_client_connect_mcs_connect_response(rdpRdp* rdp, wStream* s); BOOL rdp_client_connect_mcs_connect_response(rdpRdp* rdp, wStream* s);
BOOL rdp_client_connect_mcs_attach_user_confirm(rdpRdp* rdp, wStream* s); BOOL rdp_client_connect_mcs_attach_user_confirm(rdpRdp* rdp, wStream* s);

View File

@ -73,10 +73,7 @@ BOOL freerdp_connect(freerdp* instance)
rdp = instance->context->rdp; rdp = instance->context->rdp;
settings = instance->settings; settings = instance->settings;
if (!rdp->reconnect) IFCALLRET(instance->PreConnect, status, instance);
{
IFCALLRET(instance->PreConnect, status, instance);
}
if (settings->KeyboardLayout == KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002) if (settings->KeyboardLayout == KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002)
{ {
@ -119,10 +116,7 @@ BOOL freerdp_connect(freerdp* instance)
instance->update->dump_rfx = TRUE; instance->update->dump_rfx = TRUE;
} }
if (!rdp->reconnect) IFCALLRET(instance->PostConnect, status, instance);
{
IFCALLRET(instance->PostConnect, status, instance);
}
update_post_connect(instance->update); update_post_connect(instance->update);
@ -356,10 +350,7 @@ BOOL freerdp_disconnect(freerdp* instance)
rdp_client_disconnect(rdp); rdp_client_disconnect(rdp);
update_post_disconnect(instance->update); update_post_disconnect(instance->update);
if (!rdp->reconnect) IFCALL(instance->PostDisconnect, instance);
{
IFCALL(instance->PostDisconnect, instance);
}
if (instance->update->pcap_rfx) if (instance->update->pcap_rfx)
{ {
@ -373,17 +364,10 @@ BOOL freerdp_disconnect(freerdp* instance)
BOOL freerdp_reconnect(freerdp* instance) BOOL freerdp_reconnect(freerdp* instance)
{ {
BOOL status = TRUE; BOOL status;
rdpRdp* rdp = instance->context->rdp; rdpRdp* rdp = instance->context->rdp;
rdp->reconnect = TRUE; status = rdp_client_reconnect(rdp);
status = freerdp_disconnect(instance);
if (status)
status = freerdp_connect(instance);
rdp->reconnect = FALSE;
return status; return status;
} }

View File

@ -57,22 +57,25 @@ static const char* const INFO_TYPE_LOGON_STRINGS[] =
BOOL rdp_read_server_auto_reconnect_cookie(wStream* s, rdpSettings* settings) BOOL rdp_read_server_auto_reconnect_cookie(wStream* s, rdpSettings* settings)
{ {
ARC_SC_PRIVATE_PACKET* autoReconnectCookie; ARC_SC_PRIVATE_PACKET* autoReconnectCookie;
autoReconnectCookie = settings->ServerAutoReconnectCookie; autoReconnectCookie = settings->ServerAutoReconnectCookie;
if (Stream_GetRemainingLength(s) < 4+4+4+16) if (Stream_GetRemainingLength(s) < 28)
return FALSE; return FALSE;
Stream_Read_UINT32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */ Stream_Read_UINT32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */
Stream_Read_UINT32(s, autoReconnectCookie->version); /* version (4 bytes) */ Stream_Read_UINT32(s, autoReconnectCookie->version); /* version (4 bytes) */
Stream_Read_UINT32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */ Stream_Read_UINT32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */
Stream_Read(s, autoReconnectCookie->arcRandomBits, 16); /* arcRandomBits (16 bytes) */ Stream_Read(s, autoReconnectCookie->arcRandomBits, 16); /* arcRandomBits (16 bytes) */
if ((settings->PrintReconnectCookie) && (autoReconnectCookie->cbLen > 0)) if ((settings->PrintReconnectCookie) && (autoReconnectCookie->cbLen > 0))
{ {
char *base64; char* base64;
base64 = crypto_base64_encode((BYTE *) autoReconnectCookie, base64 = crypto_base64_encode((BYTE*) autoReconnectCookie, sizeof(ARC_SC_PRIVATE_PACKET));
sizeof(ARC_SC_PRIVATE_PACKET)); WLog_INFO(TAG, "Reconnect-cookie: %s", base64);
WLog_INFO(TAG, "Reconnect-cookie: %s", base64);
free(base64); free(base64);
} }
return TRUE; return TRUE;
} }
@ -117,6 +120,7 @@ void rdp_write_client_auto_reconnect_cookie(wStream* s, rdpSettings* settings)
/* SecurityVerifier = HMAC(AutoReconnectRandom, ClientRandom) */ /* SecurityVerifier = HMAC(AutoReconnectRandom, ClientRandom) */
hmac = crypto_hmac_new(); hmac = crypto_hmac_new();
ZeroMemory(nullRandom, sizeof(nullRandom)); ZeroMemory(nullRandom, sizeof(nullRandom));
crypto_hmac_md5_init(hmac, autoReconnectCookie->securityVerifier, 16); crypto_hmac_md5_init(hmac, autoReconnectCookie->securityVerifier, 16);
@ -231,35 +235,37 @@ void rdp_write_extended_info_packet(wStream* s, rdpSettings* settings)
cbAutoReconnectLen = (int) settings->ServerAutoReconnectCookie->cbLen; cbAutoReconnectLen = (int) settings->ServerAutoReconnectCookie->cbLen;
Stream_Write_UINT16(s, clientAddressFamily); /* clientAddressFamily */ Stream_Write_UINT16(s, clientAddressFamily); /* clientAddressFamily (2 bytes) */
Stream_Write_UINT16(s, cbClientAddress + 2); /* cbClientAddress */ Stream_Write_UINT16(s, cbClientAddress + 2); /* cbClientAddress (2 bytes) */
if (cbClientAddress > 0) if (cbClientAddress > 0)
Stream_Write(s, clientAddress, cbClientAddress); /* clientAddress */ Stream_Write(s, clientAddress, cbClientAddress); /* clientAddress */
Stream_Write_UINT16(s, 0); Stream_Write_UINT16(s, 0);
Stream_Write_UINT16(s, cbClientDir + 2); /* cbClientDir */ Stream_Write_UINT16(s, cbClientDir + 2); /* cbClientDir (2 bytes) */
if (cbClientDir > 0) if (cbClientDir > 0)
Stream_Write(s, clientDir, cbClientDir); /* clientDir */ Stream_Write(s, clientDir, cbClientDir); /* clientDir */
Stream_Write_UINT16(s, 0); Stream_Write_UINT16(s, 0);
rdp_write_client_time_zone(s, settings); /* clientTimeZone */ rdp_write_client_time_zone(s, settings); /* clientTimeZone (172 bytes) */
Stream_Write_UINT32(s, 0); /* clientSessionId, should be set to 0 */ Stream_Write_UINT32(s, 0); /* clientSessionId (4 bytes), should be set to 0 */
freerdp_performance_flags_make(settings); freerdp_performance_flags_make(settings);
Stream_Write_UINT32(s, settings->PerformanceFlags); /* performanceFlags */ Stream_Write_UINT32(s, settings->PerformanceFlags); /* performanceFlags (4 bytes) */
Stream_Write_UINT16(s, cbAutoReconnectLen); /* cbAutoReconnectLen */ Stream_Write_UINT16(s, cbAutoReconnectLen); /* cbAutoReconnectCookie (2 bytes) */
if (cbAutoReconnectLen > 0) if (cbAutoReconnectLen > 0)
{ {
CryptoHmac hmac; CryptoHmac hmac;
ARC_SC_PRIVATE_PACKET* serverCookie; ARC_SC_PRIVATE_PACKET* serverCookie;
ARC_CS_PRIVATE_PACKET* clientCookie; ARC_CS_PRIVATE_PACKET* clientCookie;
WLog_DBG(TAG, "Sending auto reconnect");
WLog_DBG(TAG, "Sending auto reconnect cookie");
serverCookie = settings->ServerAutoReconnectCookie; serverCookie = settings->ServerAutoReconnectCookie;
clientCookie = settings->ClientAutoReconnectCookie; clientCookie = settings->ClientAutoReconnectCookie;
@ -268,9 +274,10 @@ void rdp_write_extended_info_packet(wStream* s, rdpSettings* settings)
clientCookie->logonId = serverCookie->logonId; clientCookie->logonId = serverCookie->logonId;
hmac = crypto_hmac_new(); hmac = crypto_hmac_new();
if (!hmac) if (!hmac)
{ {
WLog_ERR(TAG, "unable to allocate hmac"); WLog_ERR(TAG, "unable to allocate hmac");
goto out_free; goto out_free;
} }
@ -278,7 +285,7 @@ void rdp_write_extended_info_packet(wStream* s, rdpSettings* settings)
if (settings->SelectedProtocol == PROTOCOL_RDP) if (settings->SelectedProtocol == PROTOCOL_RDP)
{ {
crypto_hmac_update(hmac, (BYTE*) (settings->ClientRandom), 32); crypto_hmac_update(hmac, (BYTE*) settings->ClientRandom, 32);
} }
else else
{ {
@ -290,16 +297,20 @@ void rdp_write_extended_info_packet(wStream* s, rdpSettings* settings)
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 }; 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 };
crypto_hmac_update(hmac, zeros, 32); crypto_hmac_update(hmac, zeros, 32);
} }
crypto_hmac_final(hmac, clientCookie->securityVerifier, 16); crypto_hmac_final(hmac, clientCookie->securityVerifier, 16);
rdp_write_client_auto_reconnect_cookie(s, settings); /* autoReconnectCookie */ rdp_write_client_auto_reconnect_cookie(s, settings); /* autoReconnectCookie */
crypto_hmac_free(hmac);
/* mark as used */ /* mark as used */
settings->ServerAutoReconnectCookie->cbLen = 0; settings->ServerAutoReconnectCookie->cbLen = 0;
crypto_hmac_free(hmac);
Stream_Write_UINT16(s, 0); /* reserved1 (2 bytes) */
Stream_Write_UINT16(s, 0); /* reserved2 (2 bytes) */
} }
/* reserved1 (2 bytes) */
/* reserved2 (2 bytes) */
out_free: out_free:
free(clientAddress); free(clientAddress);
free(clientDir); free(clientDir);
@ -527,14 +538,14 @@ void rdp_write_info_packet(wStream* s, rdpSettings* settings)
cbWorkingDir = ConvertToUnicode(CP_UTF8, 0, settings->RemoteAssistanceSessionId, -1, &workingDirW, 0) * 2; cbWorkingDir = ConvertToUnicode(CP_UTF8, 0, settings->RemoteAssistanceSessionId, -1, &workingDirW, 0) * 2;
} }
Stream_Write_UINT32(s, 0); /* CodePage */ Stream_Write_UINT32(s, 0); /* CodePage (4 bytes) */
Stream_Write_UINT32(s, flags); /* flags */ Stream_Write_UINT32(s, flags); /* flags (4 bytes) */
Stream_Write_UINT16(s, cbDomain); /* cbDomain */ Stream_Write_UINT16(s, cbDomain); /* cbDomain (2 bytes) */
Stream_Write_UINT16(s, cbUserName); /* cbUserName */ Stream_Write_UINT16(s, cbUserName); /* cbUserName (2 bytes) */
Stream_Write_UINT16(s, cbPassword); /* cbPassword */ Stream_Write_UINT16(s, cbPassword); /* cbPassword (2 bytes) */
Stream_Write_UINT16(s, cbAlternateShell); /* cbAlternateShell */ Stream_Write_UINT16(s, cbAlternateShell); /* cbAlternateShell (2 bytes) */
Stream_Write_UINT16(s, cbWorkingDir); /* cbWorkingDir */ Stream_Write_UINT16(s, cbWorkingDir); /* cbWorkingDir (2 bytes) */
if (cbDomain > 0) if (cbDomain > 0)
Stream_Write(s, domainW, cbDomain); Stream_Write(s, domainW, cbDomain);
@ -594,7 +605,7 @@ BOOL rdp_recv_client_info(rdpRdp* rdp, wStream* s)
{ {
if (securityFlags & SEC_REDIRECTION_PKT) if (securityFlags & SEC_REDIRECTION_PKT)
{ {
WLog_ERR(TAG, "Error: SEC_REDIRECTION_PKT unsupported"); WLog_ERR(TAG, "Error: SEC_REDIRECTION_PKT unsupported");
return FALSE; return FALSE;
} }
@ -602,7 +613,7 @@ BOOL rdp_recv_client_info(rdpRdp* rdp, wStream* s)
{ {
if (!rdp_decrypt(rdp, s, length - 4, securityFlags)) if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
{ {
WLog_ERR(TAG, "rdp_decrypt failed"); WLog_ERR(TAG, "rdp_decrypt failed");
return FALSE; return FALSE;
} }
} }
@ -755,7 +766,7 @@ BOOL rdp_recv_save_session_info(rdpRdp* rdp, wStream* s)
return FALSE; return FALSE;
Stream_Read_UINT32(s, infoType); /* infoType (4 bytes) */ Stream_Read_UINT32(s, infoType); /* infoType (4 bytes) */
//WLog_ERR(TAG, "%s", INFO_TYPE_LOGON_STRINGS[infoType]); //WLog_ERR(TAG, "%s", INFO_TYPE_LOGON_STRINGS[infoType]);
switch (infoType) switch (infoType)
{ {

View File

@ -654,6 +654,9 @@ BOOL rdp_recv_server_auto_reconnect_status_pdu(rdpRdp* rdp, wStream* s)
return FALSE; return FALSE;
Stream_Read_UINT32(s, arcStatus); /* arcStatus (4 bytes) */ Stream_Read_UINT32(s, arcStatus); /* arcStatus (4 bytes) */
WLog_WARN(TAG, "AutoReconnectStatus: 0x%04X", arcStatus);
return TRUE; return TRUE;
} }
@ -1424,29 +1427,60 @@ void rdp_reset(rdpRdp* rdp)
bulk_reset(rdp->bulk); bulk_reset(rdp->bulk);
crypto_rc4_free(rdp->rc4_decrypt_key); if (rdp->rc4_decrypt_key)
rdp->rc4_decrypt_key = NULL; {
crypto_rc4_free(rdp->rc4_encrypt_key); crypto_rc4_free(rdp->rc4_decrypt_key);
rdp->rc4_encrypt_key = NULL; rdp->rc4_decrypt_key = NULL;
crypto_des3_free(rdp->fips_encrypt); }
rdp->fips_encrypt = NULL;
crypto_des3_free(rdp->fips_decrypt); if (rdp->rc4_encrypt_key)
rdp->fips_decrypt = NULL; {
crypto_hmac_free(rdp->fips_hmac); crypto_rc4_free(rdp->rc4_encrypt_key);
rdp->fips_hmac = NULL; rdp->rc4_encrypt_key = NULL;
}
if (rdp->fips_encrypt)
{
crypto_des3_free(rdp->fips_encrypt);
rdp->fips_encrypt = NULL;
}
if (rdp->fips_decrypt)
{
crypto_des3_free(rdp->fips_decrypt);
rdp->fips_decrypt = NULL;
}
if (rdp->fips_hmac)
{
crypto_hmac_free(rdp->fips_hmac);
rdp->fips_hmac = NULL;
}
if (settings->ServerRandom)
{
free(settings->ServerRandom);
settings->ServerRandom = NULL;
settings->ServerRandomLength = 0;
}
if (settings->ServerCertificate)
{
free(settings->ServerCertificate);
settings->ServerCertificate = NULL;
}
if (settings->ClientAddress)
{
free(settings->ClientAddress);
settings->ClientAddress = NULL;
}
mcs_free(rdp->mcs); mcs_free(rdp->mcs);
nego_free(rdp->nego); nego_free(rdp->nego);
license_free(rdp->license); license_free(rdp->license);
transport_free(rdp->transport); transport_free(rdp->transport);
free(settings->ServerRandom);
settings->ServerRandom = NULL;
free(settings->ServerCertificate);
settings->ServerCertificate = NULL;
free(settings->ClientAddress);
settings->ClientAddress = NULL;
rdp->transport = transport_new(context); rdp->transport = transport_new(context);
rdp->transport->rdp = rdp; rdp->transport->rdp = rdp;
rdp->license = license_new(rdp); rdp->license = license_new(rdp);

View File

@ -169,7 +169,6 @@ struct rdp_rdp
BYTE fips_decrypt_key[24]; BYTE fips_decrypt_key[24];
UINT32 errorInfo; UINT32 errorInfo;
UINT32 finalize_sc_pdus; UINT32 finalize_sc_pdus;
BOOL reconnect;
BOOL disconnect; BOOL disconnect;
BOOL resendFocus; BOOL resendFocus;
BOOL deactivation_reactivation; BOOL deactivation_reactivation;

View File

@ -483,6 +483,7 @@ rdpSettings* freerdp_settings_clone(rdpSettings* settings)
_settings->RemoteAssistancePassword = _strdup(settings->RemoteAssistancePassword); /* 1027 */ _settings->RemoteAssistancePassword = _strdup(settings->RemoteAssistancePassword); /* 1027 */
_settings->RemoteAssistanceRCTicket = _strdup(settings->RemoteAssistanceRCTicket); /* 1028 */ _settings->RemoteAssistanceRCTicket = _strdup(settings->RemoteAssistanceRCTicket); /* 1028 */
_settings->AuthenticationServiceClass = _strdup(settings->AuthenticationServiceClass); /* 1098 */ _settings->AuthenticationServiceClass = _strdup(settings->AuthenticationServiceClass); /* 1098 */
_settings->AllowedTlsCiphers = _strdup(settings->AllowedTlsCiphers); /* 1101 */
_settings->PreconnectionBlob = _strdup(settings->PreconnectionBlob); /* 1155 */ _settings->PreconnectionBlob = _strdup(settings->PreconnectionBlob); /* 1155 */
_settings->KerberosKdc = _strdup(settings->KerberosKdc); /* 1344 */ _settings->KerberosKdc = _strdup(settings->KerberosKdc); /* 1344 */
_settings->KerberosRealm = _strdup(settings->KerberosRealm); /* 1345 */ _settings->KerberosRealm = _strdup(settings->KerberosRealm); /* 1345 */
@ -542,12 +543,19 @@ rdpSettings* freerdp_settings_clone(rdpSettings* settings)
{ {
_settings->ServerRandom = (BYTE*) malloc(_settings->ServerRandomLength); _settings->ServerRandom = (BYTE*) malloc(_settings->ServerRandomLength);
CopyMemory(_settings->ServerRandom, settings->ServerRandom, _settings->ServerRandomLength); CopyMemory(_settings->ServerRandom, settings->ServerRandom, _settings->ServerRandomLength);
_settings->ServerRandomLength = settings->ServerRandomLength;
} }
if (_settings->ClientRandomLength) if (_settings->ClientRandomLength)
{ {
_settings->ClientRandom = (BYTE*) malloc(_settings->ClientRandomLength); _settings->ClientRandom = (BYTE*) malloc(_settings->ClientRandomLength);
CopyMemory(_settings->ClientRandom, settings->ClientRandom, _settings->ClientRandomLength); CopyMemory(_settings->ClientRandom, settings->ClientRandom, _settings->ClientRandomLength);
_settings->ClientRandomLength = settings->ClientRandomLength;
}
if (settings->RdpServerCertificate)
{
_settings->RdpServerCertificate = certificate_clone(settings->RdpServerCertificate);
} }
_settings->ChannelCount = settings->ChannelCount; _settings->ChannelCount = settings->ChannelCount;
@ -608,9 +616,7 @@ rdpSettings* freerdp_settings_clone(rdpSettings* settings)
_settings->StaticChannelCount = settings->StaticChannelCount; _settings->StaticChannelCount = settings->StaticChannelCount;
_settings->StaticChannelArraySize = settings->StaticChannelArraySize; _settings->StaticChannelArraySize = settings->StaticChannelArraySize;
_settings->StaticChannelArray = (ADDIN_ARGV**) _settings->StaticChannelArray = (ADDIN_ARGV**) calloc(_settings->StaticChannelArraySize, sizeof(ADDIN_ARGV*));
malloc(sizeof(ADDIN_ARGV*) * _settings->StaticChannelArraySize);
ZeroMemory(_settings->StaticChannelArray, sizeof(ADDIN_ARGV*) * _settings->StaticChannelArraySize);
for (index = 0; index < _settings->StaticChannelCount; index++) for (index = 0; index < _settings->StaticChannelCount; index++)
{ {
@ -619,9 +625,7 @@ rdpSettings* freerdp_settings_clone(rdpSettings* settings)
_settings->DynamicChannelCount = settings->DynamicChannelCount; _settings->DynamicChannelCount = settings->DynamicChannelCount;
_settings->DynamicChannelArraySize = settings->DynamicChannelArraySize; _settings->DynamicChannelArraySize = settings->DynamicChannelArraySize;
_settings->DynamicChannelArray = (ADDIN_ARGV**) _settings->DynamicChannelArray = (ADDIN_ARGV**) calloc(_settings->DynamicChannelArraySize, sizeof(ADDIN_ARGV*));
malloc(sizeof(ADDIN_ARGV*) * _settings->DynamicChannelArraySize);
ZeroMemory(_settings->DynamicChannelArray, sizeof(ADDIN_ARGV*) * _settings->DynamicChannelArraySize);
for (index = 0; index < _settings->DynamicChannelCount; index++) for (index = 0; index < _settings->DynamicChannelCount; index++)
{ {
@ -651,7 +655,7 @@ void freerdp_settings_free(rdpSettings* settings)
free(settings->MonitorDefArray); free(settings->MonitorDefArray);
free(settings->ClientAddress); free(settings->ClientAddress);
free(settings->ClientDir); free(settings->ClientDir);
free(settings->PermittedTLSCiphers); free(settings->AllowedTlsCiphers);
free(settings->CertificateFile); free(settings->CertificateFile);
free(settings->PrivateKeyFile); free(settings->PrivateKeyFile);
free(settings->ConnectionFile); free(settings->ConnectionFile);

View File

@ -511,7 +511,7 @@ static CryptoCert tls_get_certificate(rdpTls* tls, BOOL peer)
if (!remote_cert) if (!remote_cert)
{ {
WLog_ERR(TAG, "failed to get the server TLS certificate"); WLog_ERR(TAG, "failed to get the server TLS certificate");
return NULL; return NULL;
} }
@ -581,11 +581,13 @@ BOOL tls_prepare(rdpTls* tls, BIO *underlying, SSL_METHOD *method, int options,
BOOL tls_prepare(rdpTls* tls, BIO *underlying, const SSL_METHOD *method, int options, BOOL clientMode) BOOL tls_prepare(rdpTls* tls, BIO *underlying, const SSL_METHOD *method, int options, BOOL clientMode)
#endif #endif
{ {
rdpSettings* settings = tls->settings;
tls->ctx = SSL_CTX_new(method); tls->ctx = SSL_CTX_new(method);
if (!tls->ctx) if (!tls->ctx)
{ {
WLog_ERR(TAG, "SSL_CTX_new failed"); WLog_ERR(TAG, "SSL_CTX_new failed");
return FALSE; return FALSE;
} }
@ -594,11 +596,11 @@ BOOL tls_prepare(rdpTls* tls, BIO *underlying, const SSL_METHOD *method, int opt
SSL_CTX_set_options(tls->ctx, options); SSL_CTX_set_options(tls->ctx, options);
SSL_CTX_set_read_ahead(tls->ctx, 1); SSL_CTX_set_read_ahead(tls->ctx, 1);
if (tls->settings->PermittedTLSCiphers) if (settings->AllowedTlsCiphers)
{ {
if (!SSL_CTX_set_cipher_list(tls->ctx, tls->settings->PermittedTLSCiphers)) if (!SSL_CTX_set_cipher_list(tls->ctx, settings->AllowedTlsCiphers))
{ {
WLog_ERR(TAG, "SSL_CTX_set_cipher_list %s failed", tls->settings->PermittedTLSCiphers); WLog_ERR(TAG, "SSL_CTX_set_cipher_list %s failed", settings->AllowedTlsCiphers);
return FALSE; return FALSE;
} }
} }
@ -607,7 +609,7 @@ BOOL tls_prepare(rdpTls* tls, BIO *underlying, const SSL_METHOD *method, int opt
if (BIO_get_ssl(tls->bio, &tls->ssl) < 0) if (BIO_get_ssl(tls->bio, &tls->ssl) < 0)
{ {
WLog_ERR(TAG, "unable to retrieve the SSL of the connection"); WLog_ERR(TAG, "unable to retrieve the SSL of the connection");
return FALSE; return FALSE;
} }
@ -645,7 +647,7 @@ int tls_do_handshake(rdpTls* tls, BOOL clientMode)
if (fd < 0) if (fd < 0)
{ {
WLog_ERR(TAG, "unable to retrieve BIO fd"); WLog_ERR(TAG, "unable to retrieve BIO fd");
return -1; return -1;
} }
@ -669,7 +671,7 @@ int tls_do_handshake(rdpTls* tls, BOOL clientMode)
#endif #endif
if (status < 0) if (status < 0)
{ {
WLog_ERR(TAG, "error during select()"); WLog_ERR(TAG, "error during select()");
return -1; return -1;
} }
} }
@ -678,21 +680,21 @@ int tls_do_handshake(rdpTls* tls, BOOL clientMode)
cert = tls_get_certificate(tls, clientMode); cert = tls_get_certificate(tls, clientMode);
if (!cert) if (!cert)
{ {
WLog_ERR(TAG, "tls_get_certificate failed to return the server certificate."); WLog_ERR(TAG, "tls_get_certificate failed to return the server certificate.");
return -1; return -1;
} }
tls->Bindings = tls_get_channel_bindings(cert->px509); tls->Bindings = tls_get_channel_bindings(cert->px509);
if (!tls->Bindings) if (!tls->Bindings)
{ {
WLog_ERR(TAG, "unable to retrieve bindings"); WLog_ERR(TAG, "unable to retrieve bindings");
verify_status = -1; verify_status = -1;
goto out; goto out;
} }
if (!crypto_cert_get_public_key(cert, &tls->PublicKey, &tls->PublicKeyLength)) if (!crypto_cert_get_public_key(cert, &tls->PublicKey, &tls->PublicKeyLength))
{ {
WLog_ERR(TAG, "crypto_cert_get_public_key failed to return the server public key."); WLog_ERR(TAG, "crypto_cert_get_public_key failed to return the server public key.");
verify_status = -1; verify_status = -1;
goto out; goto out;
} }
@ -707,7 +709,7 @@ int tls_do_handshake(rdpTls* tls, BOOL clientMode)
if (verify_status < 1) if (verify_status < 1)
{ {
WLog_ERR(TAG, "certificate not trusted, aborting."); WLog_ERR(TAG, "certificate not trusted, aborting.");
tls_disconnect(tls); tls_disconnect(tls);
verify_status = 0; verify_status = 0;
} }
@ -804,14 +806,14 @@ BOOL tls_accept(rdpTls* tls, BIO *underlying, const char* cert_file, const char*
if (SSL_use_RSAPrivateKey_file(tls->ssl, privatekey_file, SSL_FILETYPE_PEM) <= 0) if (SSL_use_RSAPrivateKey_file(tls->ssl, privatekey_file, SSL_FILETYPE_PEM) <= 0)
{ {
WLog_ERR(TAG, "SSL_CTX_use_RSAPrivateKey_file failed"); WLog_ERR(TAG, "SSL_CTX_use_RSAPrivateKey_file failed");
WLog_ERR(TAG, "PrivateKeyFile: %s", privatekey_file); WLog_ERR(TAG, "PrivateKeyFile: %s", privatekey_file);
return FALSE; return FALSE;
} }
if (SSL_use_certificate_file(tls->ssl, cert_file, SSL_FILETYPE_PEM) <= 0) if (SSL_use_certificate_file(tls->ssl, cert_file, SSL_FILETYPE_PEM) <= 0)
{ {
WLog_ERR(TAG, "SSL_use_certificate_file failed"); WLog_ERR(TAG, "SSL_use_certificate_file failed");
return FALSE; return FALSE;
} }
@ -1097,7 +1099,7 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por
if (!bio) if (!bio)
{ {
WLog_ERR(TAG, "BIO_new() failure"); WLog_ERR(TAG, "BIO_new() failure");
return -1; return -1;
} }
@ -1105,7 +1107,7 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por
if (status < 0) if (status < 0)
{ {
WLog_ERR(TAG, "PEM_write_bio_X509 failure: %d", status); WLog_ERR(TAG, "PEM_write_bio_X509 failure: %d", status);
return -1; return -1;
} }
@ -1117,7 +1119,7 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por
if (status < 0) if (status < 0)
{ {
WLog_ERR(TAG, "failed to read certificate"); WLog_ERR(TAG, "failed to read certificate");
return -1; return -1;
} }
@ -1138,7 +1140,7 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por
if (status < 0) if (status < 0)
{ {
WLog_ERR(TAG, "failed to read certificate"); WLog_ERR(TAG, "failed to read certificate");
return -1; return -1;
} }
@ -1152,7 +1154,7 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por
status = instance->VerifyX509Certificate(instance, pemCert, length, hostname, port, tls->isGatewayTransport); status = instance->VerifyX509Certificate(instance, pemCert, length, hostname, port, tls->isGatewayTransport);
} }
WLog_ERR(TAG, "(length = %d) status: %d%s", length, status, pemCert); WLog_ERR(TAG, "(length = %d) status: %d%s", length, status, pemCert);
free(pemCert); free(pemCert);
BIO_free(bio); BIO_free(bio);
@ -1312,18 +1314,18 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por
void tls_print_certificate_error(char* hostname, char* fingerprint, char *hosts_file) void tls_print_certificate_error(char* hostname, char* fingerprint, char *hosts_file)
{ {
WLog_ERR(TAG, "The host key for %s has changed", hostname); WLog_ERR(TAG, "The host key for %s has changed", hostname);
WLog_ERR(TAG, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); WLog_ERR(TAG, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
WLog_ERR(TAG, "@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @"); WLog_ERR(TAG, "@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @");
WLog_ERR(TAG, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); WLog_ERR(TAG, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
WLog_ERR(TAG, "IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!"); WLog_ERR(TAG, "IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!");
WLog_ERR(TAG, "Someone could be eavesdropping on you right now (man-in-the-middle attack)!"); WLog_ERR(TAG, "Someone could be eavesdropping on you right now (man-in-the-middle attack)!");
WLog_ERR(TAG, "It is also possible that a host key has just been changed."); WLog_ERR(TAG, "It is also possible that a host key has just been changed.");
WLog_ERR(TAG, "The fingerprint for the host key sent by the remote host is%s", fingerprint); WLog_ERR(TAG, "The fingerprint for the host key sent by the remote host is%s", fingerprint);
WLog_ERR(TAG, "Please contact your system administrator."); WLog_ERR(TAG, "Please contact your system administrator.");
WLog_ERR(TAG, "Add correct host key in %s to get rid of this message.", hosts_file); WLog_ERR(TAG, "Add correct host key in %s to get rid of this message.", hosts_file);
WLog_ERR(TAG, "Host key for %s has changed and you have requested strict checking.", hostname); WLog_ERR(TAG, "Host key for %s has changed and you have requested strict checking.", hostname);
WLog_ERR(TAG, "Host key verification failed."); WLog_ERR(TAG, "Host key verification failed.");
} }
void tls_print_certificate_name_mismatch_error(char* hostname, char* common_name, char** alt_names, int alt_names_count) void tls_print_certificate_name_mismatch_error(char* hostname, char* common_name, char** alt_names, int alt_names_count)
@ -1331,24 +1333,24 @@ void tls_print_certificate_name_mismatch_error(char* hostname, char* common_name
int index; int index;
assert(NULL != hostname); assert(NULL != hostname);
WLog_ERR(TAG, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); WLog_ERR(TAG, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
WLog_ERR(TAG, "@ WARNING: CERTIFICATE NAME MISMATCH! @"); WLog_ERR(TAG, "@ WARNING: CERTIFICATE NAME MISMATCH! @");
WLog_ERR(TAG, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); WLog_ERR(TAG, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
WLog_ERR(TAG, "The hostname used for this connection (%s) ", hostname); WLog_ERR(TAG, "The hostname used for this connection (%s) ", hostname);
WLog_ERR(TAG, "does not match %s given in the certificate:", alt_names_count < 1 ? "the name" : "any of the names"); WLog_ERR(TAG, "does not match %s given in the certificate:", alt_names_count < 1 ? "the name" : "any of the names");
WLog_ERR(TAG, "Common Name (CN):"); WLog_ERR(TAG, "Common Name (CN):");
WLog_ERR(TAG, "\t%s", common_name ? common_name : "no CN found in certificate"); WLog_ERR(TAG, "\t%s", common_name ? common_name : "no CN found in certificate");
if (alt_names_count > 0) if (alt_names_count > 0)
{ {
assert(NULL != alt_names); assert(NULL != alt_names);
WLog_ERR(TAG, "Alternative names:"); WLog_ERR(TAG, "Alternative names:");
for (index = 0; index < alt_names_count; index++) for (index = 0; index < alt_names_count; index++)
{ {
assert(alt_names[index]); assert(alt_names[index]);
WLog_ERR(TAG, "\t %s", alt_names[index]); WLog_ERR(TAG, "\t %s", alt_names[index]);
} }
} }
WLog_ERR(TAG, "A valid certificate for the wrong name should NOT be trusted!"); WLog_ERR(TAG, "A valid certificate for the wrong name should NOT be trusted!");
} }
rdpTls* tls_new(rdpSettings* settings) rdpTls* tls_new(rdpSettings* settings)