client/common: fix Remote Assistance memory leaks

This commit is contained in:
Marc-André Moreau 2014-06-29 19:57:46 -04:00
parent 90ea609576
commit 01a013f826
4 changed files with 190 additions and 18 deletions

View File

@ -43,7 +43,7 @@ int remdesk_virtual_channel_write(remdeskPlugin* remdesk, wStream* s)
return -1;
status = remdesk->channelEntryPoints.pVirtualChannelWrite(remdesk->OpenHandle,
Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s);
Stream_Buffer(s), (UINT32) Stream_Length(s), s);
if (status != CHANNEL_RC_OK)
{
@ -51,8 +51,6 @@ int remdesk_virtual_channel_write(remdeskPlugin* remdesk, wStream* s)
return -1;
}
Stream_Free(s, TRUE);
return 1;
}
@ -179,10 +177,135 @@ int remdesk_send_ctl_version_info_pdu(remdeskPlugin* remdesk)
return 1;
}
int remdesk_recv_result_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header, UINT32 *pResult)
{
UINT32 result;
if (Stream_GetRemainingLength(s) < 4)
return -1;
Stream_Read_UINT32(s, result); /* result (4 bytes) */
*pResult = result;
printf("RemdeskRecvResult: 0x%04X\n", result);
return 1;
}
int remdesk_send_ctl_authenticate_pdu(remdeskPlugin* remdesk)
{
int status;
wStream* s;
int cbExpertBlobW = 0;
WCHAR* expertBlobW = NULL;
int cbRaConnectionStringW = 0;
WCHAR* raConnectionStringW = NULL;
REMDESK_CTL_AUTHENTICATE_PDU pdu;
pdu.expertBlob = NULL;
pdu.raConnectionString = NULL;
status = ConvertToUnicode(CP_UTF8, 0, pdu.raConnectionString, -1, &raConnectionStringW, 0);
if (status <= 0)
return -1;
cbRaConnectionStringW = status * 2;
status = ConvertToUnicode(CP_UTF8, 0, pdu.expertBlob, -1, &expertBlobW, 0);
if (status <= 0)
return -1;
cbExpertBlobW = status * 2;
remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_AUTHENTICATE,
cbRaConnectionStringW + cbExpertBlobW);
s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength);
remdesk_write_ctl_header(s, &(pdu.ctlHeader));
Stream_Write(s, (BYTE*) raConnectionStringW, cbRaConnectionStringW);
Stream_Write(s, (BYTE*) expertBlobW, cbExpertBlobW);
Stream_SealLength(s);
remdesk_virtual_channel_write(remdesk, s);
free(raConnectionStringW);
free(expertBlobW);
return 1;
}
int remdesk_send_ctl_verify_password_pdu(remdeskPlugin* remdesk)
{
int status;
wStream* s;
int cbExpertBlobW = 0;
WCHAR* expertBlobW = NULL;
REMDESK_CTL_VERIFY_PASSWORD_PDU pdu;
pdu.expertBlob = NULL;
status = ConvertToUnicode(CP_UTF8, 0, pdu.expertBlob, -1, &expertBlobW, 0);
if (status <= 0)
return -1;
cbExpertBlobW = status * 2;
remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_AUTHENTICATE, cbExpertBlobW);
s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength);
remdesk_write_ctl_header(s, &(pdu.ctlHeader));
Stream_Write(s, (BYTE*) expertBlobW, cbExpertBlobW);
Stream_SealLength(s);
remdesk_virtual_channel_write(remdesk, s);
free(expertBlobW);
return 1;
}
int remdesk_send_ctl_expert_on_vista_pdu(remdeskPlugin* remdesk)
{
wStream* s;
BYTE EncryptedPassword[32];
REMDESK_CTL_EXPERT_ON_VISTA_PDU pdu;
ZeroMemory(EncryptedPassword, 32);
pdu.EncryptedPasswordLength = 32;
pdu.EncryptedPassword = (BYTE*) EncryptedPassword;
remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_EXPERT_ON_VISTA,
pdu.EncryptedPasswordLength);
s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength);
remdesk_write_ctl_header(s, &(pdu.ctlHeader));
Stream_Write(s, pdu.EncryptedPassword, pdu.EncryptedPasswordLength);
Stream_SealLength(s);
remdesk_virtual_channel_write(remdesk, s);
return 1;
}
int remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header)
{
int status = 1;
UINT32 msgType;
UINT32 msgType = 0;
UINT32 result = 0;
if (Stream_GetRemainingLength(s) < 4)
return -1;
@ -197,6 +320,7 @@ int remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEA
break;
case REMDESK_CTL_RESULT:
status = remdesk_recv_result_pdu(remdesk, s, header, &result);
break;
case REMDESK_CTL_AUTHENTICATE:
@ -211,6 +335,10 @@ int remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEA
case REMDESK_CTL_VERSIONINFO:
status = remdesk_recv_ctl_version_info_pdu(remdesk, s, header);
if (status >= 0)
status = remdesk_send_ctl_version_info_pdu(remdesk);
break;
case REMDESK_CTL_ISCONNECTED:

View File

@ -134,13 +134,13 @@ int freerdp_client_assistance_crypt_derive_key_sha1(BYTE* hash, int hashLength,
if (!buffer)
return -1;
SHA_Init(&hashCtx);
SHA_Update(&hashCtx, pad1, 64);
SHA_Final((void*) buffer, &hashCtx);
SHA1_Init(&hashCtx);
SHA1_Update(&hashCtx, pad1, 64);
SHA1_Final((void*) buffer, &hashCtx);
SHA_Init(&hashCtx);
SHA_Update(&hashCtx, pad2, 64);
SHA_Final((void*) &buffer[hashLength], &hashCtx);
SHA1_Init(&hashCtx);
SHA1_Update(&hashCtx, pad2, 64);
SHA1_Final((void*) &buffer[hashLength], &hashCtx);
CopyMemory(key, buffer, keyLength);
@ -259,6 +259,10 @@ int freerdp_client_assistance_decrypt1(rdpAssistanceFile* file, const char* pass
printf("EncryptedPassStub (%d):\n", file->EncryptedPassStubLength);
winpr_HexDump(file->EncryptedPassStub, file->EncryptedPassStubLength);
free(PlainBlob);
free(PasswordW);
free(PassStubW);
return 1;
}
@ -272,6 +276,7 @@ int freerdp_client_assistance_decrypt2(rdpAssistanceFile* file, const char* pass
BYTE *pbIn, *pbOut;
int cbOut, cbIn, cbFinal;
BYTE DerivedKey[AES_BLOCK_SIZE];
BYTE InitializationVector[AES_BLOCK_SIZE];
BYTE PasswordHash[SHA_DIGEST_LENGTH];
status = ConvertToUnicode(CP_UTF8, 0, password, -1, &PasswordW, 0);
@ -281,9 +286,9 @@ int freerdp_client_assistance_decrypt2(rdpAssistanceFile* file, const char* pass
cbPasswordW = (status - 1) * 2;
SHA_Init(&shaCtx);
SHA_Update(&shaCtx, PasswordW, cbPasswordW);
SHA_Final((void*) PasswordHash, &shaCtx);
SHA1_Init(&shaCtx);
SHA1_Update(&shaCtx, PasswordW, cbPasswordW);
SHA1_Final((void*) PasswordHash, &shaCtx);
status = freerdp_client_assistance_crypt_derive_key_sha1(PasswordHash, sizeof(PasswordHash),
DerivedKey, sizeof(DerivedKey));
@ -291,11 +296,19 @@ int freerdp_client_assistance_decrypt2(rdpAssistanceFile* file, const char* pass
if (status < 0)
return -1;
ZeroMemory(InitializationVector, sizeof(InitializationVector));
EVP_CIPHER_CTX_init(&aesDec);
status = EVP_DecryptInit_ex(&aesDec, EVP_aes_128_cbc(), NULL, NULL, NULL);
if (status != 1)
return -1;
EVP_CIPHER_CTX_set_key_length(&aesDec, (128 / 8));
EVP_CIPHER_CTX_set_padding(&aesDec, 0);
status = EVP_DecryptInit_ex(&aesDec, EVP_aes_128_cbc(), NULL, DerivedKey, NULL);
status = EVP_DecryptInit_ex(&aesDec, EVP_aes_128_cbc(), NULL, DerivedKey, InitializationVector);
if (status != 1)
return -1;
@ -303,7 +316,7 @@ int freerdp_client_assistance_decrypt2(rdpAssistanceFile* file, const char* pass
cbOut = cbFinal = 0;
cbIn = file->EncryptedLHTicketLength;
file->ConnectionString2 = (char*) calloc(1, cbOut + AES_BLOCK_SIZE);
file->ConnectionString2 = (char*) calloc(1, cbIn + AES_BLOCK_SIZE);
if (!file->ConnectionString2)
return -1;
@ -318,8 +331,6 @@ int freerdp_client_assistance_decrypt2(rdpAssistanceFile* file, const char* pass
status = EVP_DecryptFinal_ex(&aesDec, pbOut + cbOut, &cbFinal);
/* FIXME: still fails */
if (status != 1)
{
fprintf(stderr, "EVP_DecryptFinal_ex failure\n");
@ -328,6 +339,8 @@ int freerdp_client_assistance_decrypt2(rdpAssistanceFile* file, const char* pass
EVP_CIPHER_CTX_cleanup(&aesDec);
free(PasswordW);
return 1;
}
@ -808,8 +821,13 @@ void freerdp_client_assistance_file_free(rdpAssistanceFile* file)
free(file->LHTicket);
free(file->RCTicket);
free(file->PassStub);
free(file->ConnectionString1);
free(file->ConnectionString2);
free(file->EncryptedLHTicket);
free(file->RASessionId);
free(file->RASpecificParams);
free(file->MachineAddress);
free(file->EncryptedPassStub);
free(file);
}

View File

@ -146,7 +146,7 @@ int TestClientAssistance(int argc, char* argv[])
{
test_msrsc_incident_file_type1();
//test_msrsc_incident_file_type2();
test_msrsc_incident_file_type2();
return 0;
}

View File

@ -66,5 +66,31 @@ struct _REMDESK_CTL_VERSION_INFO_PDU
};
typedef struct _REMDESK_CTL_VERSION_INFO_PDU REMDESK_CTL_VERSION_INFO_PDU;
struct _REMDESK_CTL_AUTHENTICATE_PDU
{
REMDESK_CTL_HEADER ctlHeader;
char* raConnectionString;
char* expertBlob;
};
typedef struct _REMDESK_CTL_AUTHENTICATE_PDU REMDESK_CTL_AUTHENTICATE_PDU;
struct _REMDESK_CTL_VERIFY_PASSWORD_PDU
{
REMDESK_CTL_HEADER ctlHeader;
char* expertBlob;
};
typedef struct _REMDESK_CTL_VERIFY_PASSWORD_PDU REMDESK_CTL_VERIFY_PASSWORD_PDU;
struct _REMDESK_CTL_EXPERT_ON_VISTA_PDU
{
REMDESK_CTL_HEADER ctlHeader;
BYTE* EncryptedPassword;
UINT32 EncryptedPasswordLength;
};
typedef struct _REMDESK_CTL_EXPERT_ON_VISTA_PDU REMDESK_CTL_EXPERT_ON_VISTA_PDU;
#endif /* FREERDP_CHANNEL_REMDESK_H */