client/common: fix Remote Assistance memory leaks
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Sun, 29 Jun 2014 23:57:46 +0000 (19:57 -0400)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Sun, 29 Jun 2014 23:57:46 +0000 (19:57 -0400)
channels/remdesk/client/remdesk_main.c
client/common/assistance.c
client/common/test/TestClientAssistance.c
include/freerdp/channels/remdesk.h

index f740086..4c41f64 100644 (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:
index 5ea6793..d0544a4 100644 (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);
 }
index c6ec99d..b2802f5 100644 (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;
 }
index f8557ca..1613e2e 100644 (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 */