assistance v2 support
authorArmin Novak <armin.novak@thincast.com>
Thu, 8 Nov 2018 08:27:57 +0000 (09:27 +0100)
committerArmin Novak <armin.novak@thincast.com>
Thu, 22 Nov 2018 10:11:31 +0000 (11:11 +0100)
channels/remdesk/client/remdesk_main.h
client/common/client.c
client/common/cmdline.c
include/freerdp/assistance.h
include/freerdp/client.h
libfreerdp/common/assistance.c
libfreerdp/common/test/TestCommonAssistance.c

index 13ae5c7..852e18e 100644 (file)
@@ -55,7 +55,7 @@ struct remdesk_plugin
        UINT32 Version;
        char* ExpertBlob;
        BYTE* EncryptedPassStub;
-       int EncryptedPassStubSize;
+       size_t EncryptedPassStubSize;
        rdpContext* rdpcontext;
 };
 typedef struct remdesk_plugin remdeskPlugin;
index 06146a4..114d930 100644 (file)
@@ -303,24 +303,38 @@ out:
 }
 
 int freerdp_client_settings_parse_assistance_file(rdpSettings* settings,
-        const char* filename)
+        int argc, char* argv[])
 {
-       int status;
+       int status, x;
        int ret = -1;
+       char* filename;
+       char* password = NULL;
        rdpAssistanceFile* file;
+
+       if (!settings || !argv || (argc < 1))
+               return -1;
+
+       filename = argv[1];
+
+       for (x = 2; x < argc; x++)
+       {
+               const char* key = strstr(argv[x], "assistance:");
+
+               if (key)
+                       password = strchr(key, ':') + 1;
+       }
+
        file = freerdp_assistance_file_new();
 
        if (!file)
                return -1;
 
-       status = freerdp_assistance_parse_file(file, filename);
+       status = freerdp_assistance_parse_file(file, filename, password);
 
        if (status < 0)
                goto out;
 
-       status = freerdp_client_populate_settings_from_assistance_file(file, settings);
-
-       if (status < 0)
+       if (!freerdp_client_populate_settings_from_assistance_file(file, settings))
                goto out;
 
        ret = 0;
index 103b4d2..fb3ab8b 100644 (file)
@@ -1410,7 +1410,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
                if (assist)
                {
                        if (freerdp_client_settings_parse_assistance_file(settings,
-                               argv[1]) < 0)
+                               argc, argv) < 0)
                                return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
                }
 
@@ -2673,13 +2673,6 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
                {
                        settings->PrintReconnectCookie = enable;
                }
-               CommandLineSwitchCase(arg, "assistance")
-               {
-                       settings->RemoteAssistanceMode = TRUE;
-
-                       if (!copy_value(arg->Value, &settings->RemoteAssistancePassword))
-                               return COMMAND_LINE_ERROR_MEMORY;
-               }
                CommandLineSwitchCase(arg, "pwidth")
                {
                        unsigned long val = strtoul(arg->Value, NULL, 0);
index 48301a2..1c3663b 100644 (file)
 #include <freerdp/api.h>
 #include <freerdp/freerdp.h>
 
-struct rdp_assistance_file
-{
-       UINT32 Type;
-
-       char* Username;
-       char* LHTicket;
-       char* RCTicket;
-       char* PassStub;
-       UINT32 DtStart;
-       UINT32 DtLength;
-       BOOL LowSpeed;
-       BOOL RCTicketEncrypted;
-
-       char* ConnectionString1;
-       char* ConnectionString2;
-
-       BYTE* EncryptedPassStub;
-       int EncryptedPassStubLength;
-
-       BYTE* EncryptedLHTicket;
-       int EncryptedLHTicketLength;
-
-       char* MachineAddress;
-       UINT32 MachinePort;
-
-       UINT32 MachineCount;
-       char** MachineAddresses;
-       UINT32* MachinePorts;
-
-       char* RASessionId;
-       char* RASpecificParams;
-};
 typedef struct rdp_assistance_file rdpAssistanceFile;
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-FREERDP_API BYTE* freerdp_assistance_hex_string_to_bin(const char* str, int* size);
-FREERDP_API char* freerdp_assistance_bin_to_hex_string(const BYTE* data, int size);
-
-FREERDP_API int freerdp_assistance_parse_connection_string1(rdpAssistanceFile* file);
-FREERDP_API int freerdp_assistance_parse_connection_string2(rdpAssistanceFile* file);
+FREERDP_API BYTE* freerdp_assistance_hex_string_to_bin(const char* str, size_t* size);
+FREERDP_API char* freerdp_assistance_bin_to_hex_string(const BYTE* data, size_t size);
 
 FREERDP_API char* freerdp_assistance_generate_pass_stub(DWORD flags);
 FREERDP_API char* freerdp_assistance_construct_expert_blob(const char* name, const char* pass);
-FREERDP_API BYTE* freerdp_assistance_encrypt_pass_stub(const char* password, const char* passStub, int* pEncryptedSize);
+FREERDP_API BYTE* freerdp_assistance_encrypt_pass_stub(const char* password, const char* passStub,
+        size_t* pEncryptedSize);
 
-FREERDP_API int freerdp_assistance_parse_file_buffer(rdpAssistanceFile* file, const char* buffer, size_t size);
-FREERDP_API int freerdp_assistance_parse_file(rdpAssistanceFile* file, const char* name);
-FREERDP_API int freerdp_assistance_decrypt(rdpAssistanceFile* file, const char* password);
+FREERDP_API int freerdp_assistance_parse_file_buffer(rdpAssistanceFile* file, const char* buffer,
+        size_t size, const char* password);
+FREERDP_API int freerdp_assistance_parse_file(rdpAssistanceFile* file, const char* name,
+        const char* password);
 
-FREERDP_API int freerdp_client_populate_settings_from_assistance_file(rdpAssistanceFile* file, rdpSettings* settings);
+FREERDP_API BOOL freerdp_client_populate_settings_from_assistance_file(rdpAssistanceFile* file,
+        rdpSettings* settings);
+FREERDP_API BOOL freerdp_assistance_get_encrypted_pass_stub(rdpAssistanceFile* file,
+        const char** pwd, size_t* size);
 
 FREERDP_API rdpAssistanceFile* freerdp_assistance_file_new(void);
 FREERDP_API void freerdp_assistance_file_free(rdpAssistanceFile* file);
 
+FREERDP_API void freerdp_assistance_print_file(rdpAssistanceFile* file, wLog* log, DWORD level);
+
 #ifdef __cplusplus
 }
 #endif
index c6267bc..25049c0 100644 (file)
@@ -96,7 +96,7 @@ FREERDP_API int freerdp_client_settings_write_connection_file(const rdpSettings*
         const char* filename, BOOL unicode);
 
 FREERDP_API int freerdp_client_settings_parse_assistance_file(rdpSettings* settings,
-        const char* filename);
+        int argc, char* argv[]);
 
 FREERDP_API BOOL client_cli_authenticate(freerdp* instance, char** username, char** password,
         char** domain);
index a852b69..c80efc2 100644 (file)
 
 #define TAG FREERDP_TAG("common")
 
+
+struct rdp_assistance_file
+{
+       UINT32 Type;
+
+       char* Username;
+       char* LHTicket;
+       char* RCTicket;
+       char* PassStub;
+       UINT32 DtStart;
+       UINT32 DtLength;
+       BOOL LowSpeed;
+       BOOL RCTicketEncrypted;
+
+       char* ConnectionString1;
+       char* ConnectionString2;
+
+       BYTE* EncryptedPassStub;
+       size_t EncryptedPassStubLength;
+
+       BYTE* EncryptedLHTicket;
+       size_t EncryptedLHTicketLength;
+
+       char* MachineAddress;
+       UINT32 MachinePort;
+
+       UINT32 MachineCount;
+       char** MachineAddresses;
+       UINT32* MachinePorts;
+
+       char* RASessionId;
+       char* RASpecificParams;
+
+       char* filename;
+       char* password;
+};
+
 /**
  * Password encryption in establishing a remote assistance session of type 1:
  * http://blogs.msdn.com/b/openspecification/archive/2011/10/31/password-encryption-in-establishing-a-remote-assistance-session-of-type-1.aspx
  * Use the first n bytes of the result of step 5 as the derived key.
  */
 
-int freerdp_assistance_crypt_derive_key_sha1(BYTE* hash, int hashLength, BYTE* key, int keyLength)
+static BOOL freerdp_assistance_crypt_derive_key_sha1(BYTE* hash, size_t hashLength, BYTE* key,
+        size_t keyLength)
 {
-       int rc = -1;
-       int i;
+       BOOL rc = FALSE;
+       size_t i;
        BYTE* buffer;
        BYTE pad1[64];
        BYTE pad2[64];
@@ -101,26 +139,29 @@ int freerdp_assistance_crypt_derive_key_sha1(BYTE* hash, int hashLength, BYTE* k
                goto fail;
 
        CopyMemory(key, buffer, keyLength);
-       rc = 1;
+       rc = TRUE;
 fail:
        free(buffer);
        return rc;
 }
 
-int freerdp_assistance_parse_address_list(rdpAssistanceFile* file, char* list)
+static BOOL freerdp_assistance_parse_address_list(rdpAssistanceFile* file, const char* list)
 {
-       int i;
+       size_t i;
        char* p;
        char* q;
        char* str;
-       int count;
-       int length;
-       char** tokens;
-       count = 1;
+       size_t count = 1;
+       size_t length;
+       char** tokens = NULL;
+
+       if (!file || !list)
+               return FALSE;
+
        str = _strdup(list);
 
        if (!str)
-               return -1;
+               return FALSE;
 
        length = strlen(str);
 
@@ -130,13 +171,13 @@ int freerdp_assistance_parse_address_list(rdpAssistanceFile* file, char* list)
                        count++;
        }
 
+       if (count > UINT32_MAX)
+               goto out;
+
        tokens = (char**) calloc(count, sizeof(char*));
 
        if (!tokens)
-       {
-               free(str);
-               return -1;
-       }
+               goto out;
 
        count = 0;
        tokens[count++] = str;
@@ -150,7 +191,7 @@ int freerdp_assistance_parse_address_list(rdpAssistanceFile* file, char* list)
                }
        }
 
-       file->MachineCount = count;
+       file->MachineCount = (UINT32)count;
        file->MachineAddresses = (char**) calloc(count, sizeof(char*));
        file->MachinePorts = (UINT32*) calloc(count, sizeof(UINT32));
 
@@ -175,7 +216,7 @@ int freerdp_assistance_parse_address_list(rdpAssistanceFile* file, char* list)
                        if ((errno != 0) || (val > UINT32_MAX))
                                goto out;
 
-                       file->MachinePorts[i] = val;
+                       file->MachinePorts[i] = (UINT32)val;
                }
 
                if (!file->MachineAddresses[i])
@@ -218,7 +259,7 @@ int freerdp_assistance_parse_address_list(rdpAssistanceFile* file, char* list)
                        if ((errno != 0) || (val > UINT32_MAX))
                                goto out;
 
-                       file->MachinePort = val;
+                       file->MachinePort = (UINT32)val;
                }
 
                if (!file->MachineAddress)
@@ -229,7 +270,7 @@ int freerdp_assistance_parse_address_list(rdpAssistanceFile* file, char* list)
 
        free(tokens);
        free(str);
-       return 1;
+       return TRUE;
 out:
 
        if (file->MachineAddresses)
@@ -245,17 +286,21 @@ out:
        file->MachineAddresses = NULL;
        free(tokens);
        free(str);
-       return -1;
+       return FALSE;
 }
 
-int freerdp_assistance_parse_connection_string1(rdpAssistanceFile* file)
+static BOOL freerdp_assistance_parse_connection_string1(rdpAssistanceFile* file)
 {
-       int i;
+       size_t i;
        char* str;
        int count;
-       int length;
+       size_t length;
        char* tokens[8];
-       int ret = -1;
+       BOOL rc = FALSE;
+
+       if (!file || !file->RCTicket)
+               return FALSE;
+
        /**
         * <ProtocolVersion>,<protocolType>,<machineAddressList>,<assistantAccountPwd>,
         * <RASessionID>,<RASessionName>,<RASessionPwd>,<protocolSpecificParms>
@@ -264,7 +309,7 @@ int freerdp_assistance_parse_connection_string1(rdpAssistanceFile* file)
        str = _strdup(file->RCTicket);
 
        if (!str)
-               return -1;
+               goto error;
 
        length = strlen(str);
 
@@ -314,14 +359,13 @@ int freerdp_assistance_parse_connection_string1(rdpAssistanceFile* file)
        if (!file->RASpecificParams)
                goto error;
 
-       ret = freerdp_assistance_parse_address_list(file, tokens[2]);
+       if (!freerdp_assistance_parse_address_list(file, tokens[2]))
+               goto error;
+
+       rc = TRUE;
 error:
        free(str);
-
-       if (ret != 1)
-               return -1;
-
-       return 1;
+       return rc;
 }
 
 /**
@@ -340,25 +384,29 @@ error:
  * </E>
  */
 
-int freerdp_assistance_parse_connection_string2(rdpAssistanceFile* file)
+static BOOL freerdp_assistance_parse_connection_string2(rdpAssistanceFile* file)
 {
        char* str;
        char* tag;
        char* end;
        char* p;
-       int ret = -1;
+       BOOL rc = FALSE;
+
+       if (!file || !file->ConnectionString2)
+               return FALSE;
+
        str = file->ConnectionString2;
 
        if (!strstr(str, "<E>"))
-               return -1;
+               return FALSE;
 
        if (!strstr(str, "<C>"))
-               return -1;
+               return FALSE;
 
        str = _strdup(file->ConnectionString2);
 
        if (!str)
-               return -1;
+               goto out_fail;
 
        if (!(tag = strstr(str, "<A")))
                goto out_fail;
@@ -440,7 +488,7 @@ int freerdp_assistance_parse_connection_string2(rdpAssistanceFile* file)
                        if ((errno != 0) || (val == 0) || (val > UINT16_MAX))
                                goto out_fail;
 
-                       port = val;
+                       port = (UINT16)val;
                }
                p = strstr(q, " N=\"");
 
@@ -477,17 +525,17 @@ int freerdp_assistance_parse_connection_string2(rdpAssistanceFile* file)
                p = strstr(q, "<L P=\"");
        }
 
-       ret = 1;
+       rc = TRUE;
 out_fail:
        free(str);
-       return ret;
+       return rc;
 }
 
 char* freerdp_assistance_construct_expert_blob(const char* name, const char* pass)
 {
-       int size;
-       int nameLength;
-       int passLength;
+       size_t size;
+       size_t nameLength;
+       size_t passLength;
        char* ExpertBlob = NULL;
 
        if (!name || !pass)
@@ -501,7 +549,7 @@ char* freerdp_assistance_construct_expert_blob(const char* name, const char* pas
        if (!ExpertBlob)
                return NULL;
 
-       sprintf_s(ExpertBlob, size, "%d;NAME=%s%d;PASS=%s",
+       sprintf_s(ExpertBlob, size, "%"PRIdz";NAME=%s%"PRIdz";PASS=%s",
                  nameLength, name, passLength, pass);
        return ExpertBlob;
 }
@@ -551,16 +599,17 @@ char* freerdp_assistance_generate_pass_stub(DWORD flags)
 }
 
 BYTE* freerdp_assistance_encrypt_pass_stub(const char* password, const char* passStub,
-        int* pEncryptedSize)
+        size_t* pEncryptedSize)
 {
        BOOL rc;
        int status;
-       int cbPasswordW;
-       int cbPassStubW;
-       int EncryptedSize;
+       size_t cbPasswordW;
+       size_t cbPassStubW;
+       size_t EncryptedSize;
        BYTE PasswordHash[WINPR_MD5_DIGEST_LENGTH];
-       WINPR_CIPHER_CTX* rc4Ctx;
-       BYTE* pbIn, *pbOut;
+       WINPR_CIPHER_CTX* rc4Ctx = NULL;
+       BYTE* pbIn = NULL;
+       BYTE* pbOut = NULL;
        size_t cbOut, cbIn, cbFinal;
        WCHAR* PasswordW = NULL;
        WCHAR* PassStubW = NULL;
@@ -569,179 +618,151 @@ BYTE* freerdp_assistance_encrypt_pass_stub(const char* password, const char* pas
        if (status <= 0)
                return NULL;
 
-       cbPasswordW = (status - 1) * 2;
+       cbPasswordW = (size_t)(status - 1) * 2UL;
 
        if (!winpr_Digest(WINPR_MD_MD5, (BYTE*)PasswordW, cbPasswordW, (BYTE*) PasswordHash,
                          sizeof(PasswordHash)))
-       {
-               free(PasswordW);
-               return NULL;
-       }
+               goto fail;
 
        status = ConvertToUnicode(CP_UTF8, 0, passStub, -1, &PassStubW, 0);
 
        if (status <= 0)
-       {
-               free(PasswordW);
-               return NULL;
-       }
+               goto fail;
 
-       cbPassStubW = (status - 1) * 2;
+       cbPassStubW = (size_t)(status - 1) * 2UL;
        EncryptedSize = cbPassStubW + 4;
        pbIn = (BYTE*) calloc(1, EncryptedSize);
        pbOut = (BYTE*) calloc(1, EncryptedSize);
 
        if (!pbIn || !pbOut)
-       {
-               free(PasswordW);
-               free(PassStubW);
-               free(pbIn);
-               free(pbOut);
-               return NULL;
-       }
+               goto fail;
 
-       if (!EncryptedSize)
-       {
-               free(PasswordW);
-               free(PassStubW);
-               free(pbIn);
-               free(pbOut);
-               return NULL;
-       }
+       if ((EncryptedSize == 0) || (cbPassStubW > UINT32_MAX))
+               goto fail;
 
-       *((UINT32*) pbIn) = cbPassStubW;
+       *((UINT32*) pbIn) = (UINT32)cbPassStubW;
        CopyMemory(&pbIn[4], PassStubW, cbPassStubW);
-       free(PasswordW);
-       free(PassStubW);
        rc4Ctx = winpr_Cipher_New(WINPR_CIPHER_ARC4_128, WINPR_ENCRYPT,
                                  PasswordHash, NULL);
 
        if (!rc4Ctx)
        {
                WLog_ERR(TAG,  "EVP_CipherInit_ex failure");
-               free(pbOut);
-               free(pbIn);
-               return NULL;
+               goto fail;
        }
 
        cbOut = cbFinal = 0;
        cbIn = EncryptedSize;
        rc = winpr_Cipher_Update(rc4Ctx, pbIn, cbIn, pbOut, &cbOut);
-       free(pbIn);
 
        if (!rc)
        {
                WLog_ERR(TAG,  "EVP_CipherUpdate failure");
-               winpr_Cipher_Free(rc4Ctx);
-               free(pbOut);
-               return NULL;
+               goto fail;
        }
 
        if (!winpr_Cipher_Final(rc4Ctx, pbOut + cbOut, &cbFinal))
        {
                WLog_ERR(TAG,  "EVP_CipherFinal_ex failure");
-               winpr_Cipher_Free(rc4Ctx);
-               free(pbOut);
-               return NULL;
+               goto fail;
        }
 
        winpr_Cipher_Free(rc4Ctx);
+       free(pbIn);
+       free(PasswordW);
+       free(PassStubW);
        *pEncryptedSize = EncryptedSize;
        return pbOut;
+fail:
+       winpr_Cipher_Free(rc4Ctx);
+       free(PasswordW);
+       free(PassStubW);
+       free(pbIn);
+       free(pbOut);
+       return NULL;
 }
 
-int freerdp_assistance_decrypt2(rdpAssistanceFile* file, const char* password)
+static BOOL freerdp_assistance_decrypt2(rdpAssistanceFile* file, const char* password)
 {
-       int status;
-       int cbPasswordW;
+       BOOL rc = FALSE;
+       int status = 0;
+       size_t cbPasswordW;
        int cchOutW = 0;
        WCHAR* pbOutW = NULL;
-       WINPR_CIPHER_CTX* aesDec;
+       WINPR_CIPHER_CTX* aesDec = NULL;
        WCHAR* PasswordW = NULL;
-       BYTE* pbIn, *pbOut;
+       BYTE* pbIn = NULL;
+       BYTE* pbOut = NULL;
        size_t cbOut, cbIn, cbFinal;
        BYTE DerivedKey[WINPR_AES_BLOCK_SIZE];
        BYTE InitializationVector[WINPR_AES_BLOCK_SIZE];
        BYTE PasswordHash[WINPR_SHA1_DIGEST_LENGTH];
+
+       if (!file || !password)
+               return FALSE;
+
        status = ConvertToUnicode(CP_UTF8, 0, password, -1, &PasswordW, 0);
 
        if (status <= 0)
-               return -1;
+               return FALSE;
 
-       cbPasswordW = (status - 1) * 2;
+       cbPasswordW = (size_t)(status - 1) * 2UL;
 
        if (!winpr_Digest(WINPR_MD_SHA1, (BYTE*)PasswordW, cbPasswordW, PasswordHash, sizeof(PasswordHash)))
-       {
-               free(PasswordW);
-               return -1;
-       }
-
-       status = freerdp_assistance_crypt_derive_key_sha1(PasswordHash, sizeof(PasswordHash),
-                DerivedKey, sizeof(DerivedKey));
+               goto fail;
 
-       if (status < 0)
-       {
-               free(PasswordW);
-               return -1;
-       }
+       if (!freerdp_assistance_crypt_derive_key_sha1(PasswordHash, sizeof(PasswordHash),
+               DerivedKey, sizeof(DerivedKey)))
+               goto fail;
 
        ZeroMemory(InitializationVector, sizeof(InitializationVector));
        aesDec = winpr_Cipher_New(WINPR_CIPHER_AES_128_CBC, WINPR_DECRYPT,
                                  DerivedKey, InitializationVector);
 
        if (!aesDec)
-       {
-               free(PasswordW);
-               return -1;
-       }
+               goto fail;
 
        cbOut = cbFinal = 0;
-       cbIn = file->EncryptedLHTicketLength;
+       cbIn = (size_t)file->EncryptedLHTicketLength;
        pbIn = (BYTE*) file->EncryptedLHTicket;
        pbOut = (BYTE*) calloc(1, cbIn + WINPR_AES_BLOCK_SIZE + 2);
 
        if (!pbOut)
-       {
-               winpr_Cipher_Free(aesDec);
-               free(PasswordW);
-               return -1;
-       }
+               goto fail;
 
        if (!winpr_Cipher_Update(aesDec, pbIn, cbIn, pbOut, &cbOut))
-       {
-               winpr_Cipher_Free(aesDec);
-               free(PasswordW);
-               free(pbOut);
-               return -1;
-       }
+               goto fail;
 
        if (!winpr_Cipher_Final(aesDec, pbOut + cbOut, &cbFinal))
        {
                WLog_ERR(TAG,  "EVP_DecryptFinal_ex failure");
-               winpr_Cipher_Free(aesDec);
-               free(PasswordW);
-               free(pbOut);
-               return -1;
+               goto fail;
        }
 
-       winpr_Cipher_Free(aesDec);
        cbOut += cbFinal;
        cbFinal = 0;
        pbOutW = (WCHAR*) pbOut;
-       cchOutW = cbOut / 2;
+
+       if (cbOut > INT_MAX / 2)
+               goto fail;
+
+       cchOutW = (int)cbOut / 2;
        file->ConnectionString2 = NULL;
        status = ConvertFromUnicode(CP_UTF8, 0, pbOutW, cchOutW, &file->ConnectionString2, 0, NULL, NULL);
-       free(PasswordW);
-       free(pbOut);
 
        if (status <= 0)
-       {
-               return -1;
-       }
+               goto fail;
 
-       status = freerdp_assistance_parse_connection_string2(file);
+       if (!freerdp_assistance_parse_connection_string2(file))
+               goto fail;
+
+       rc = TRUE;
+fail:
+       winpr_Cipher_Free(aesDec);
+       free(PasswordW);
+       free(pbOut);
        WLog_DBG(TAG, "freerdp_assistance_parse_connection_string2: %d", status);
-       return status;
+       return rc;
 }
 
 int freerdp_assistance_decrypt(rdpAssistanceFile* file, const char* password)
@@ -755,18 +776,18 @@ int freerdp_assistance_decrypt(rdpAssistanceFile* file, const char* password)
 
        if (file->Type > 1)
        {
-               status = freerdp_assistance_decrypt2(file, password);
+               if (!freerdp_assistance_decrypt2(file, password))
+                       status = -1;
        }
 
        return status;
 }
 
-BYTE* freerdp_assistance_hex_string_to_bin(const char* str, int* size)
+BYTE* freerdp_assistance_hex_string_to_bin(const char* str, size_t* size)
 {
-       char c;
-       int length;
+       size_t length;
        BYTE* buffer;
-       int i, ln, hn;
+       size_t i;
        length = strlen(str);
 
        if ((length % 2) != 0)
@@ -781,6 +802,8 @@ BYTE* freerdp_assistance_hex_string_to_bin(const char* str, int* size)
 
        for (i = 0; i < length; i++)
        {
+               int hn, ln;
+               char c;
                hn = ln = 0;
                c = str[(i * 2) + 0];
 
@@ -800,15 +823,15 @@ BYTE* freerdp_assistance_hex_string_to_bin(const char* str, int* size)
                else if ((c >= 'A') && (c <= 'F'))
                        ln = (c - 'A') + 10;
 
-               buffer[i] = (hn << 4) | ln;
+               buffer[i] = ((hn << 4) | ln) & 0xFF;
        }
 
        return buffer;
 }
 
-char* freerdp_assistance_bin_to_hex_string(const BYTE* data, int size)
+char* freerdp_assistance_bin_to_hex_string(const BYTE* data, size_t size)
 {
-       int i;
+       size_t i;
        char* p;
        int ln, hn;
        char bin2hex[] = "0123456789ABCDEF";
@@ -829,7 +852,8 @@ char* freerdp_assistance_bin_to_hex_string(const BYTE* data, int size)
        return p;
 }
 
-int freerdp_assistance_parse_file_buffer(rdpAssistanceFile* file, const char* buffer, size_t size)
+int freerdp_assistance_parse_file_buffer(rdpAssistanceFile* file, const char* buffer, size_t size,
+        const char* password)
 {
        char* p;
        char* q;
@@ -1032,14 +1056,21 @@ int freerdp_assistance_parse_file_buffer(rdpAssistanceFile* file, const char* bu
        }
 
        file->Type = (file->LHTicket) ? 2 : 1;
+       status = 0;
 
        if (file->LHTicket)
        {
                file->EncryptedLHTicket = freerdp_assistance_hex_string_to_bin(file->LHTicket,
                                          &file->EncryptedLHTicketLength);
-       }
 
-       status = freerdp_assistance_parse_connection_string1(file);
+               if (!freerdp_assistance_decrypt2(file, password))
+                       status = -1;
+       }
+       else
+       {
+               if (!freerdp_assistance_parse_connection_string1(file))
+                       status = -1;
+       }
 
        if (status < 0)
        {
@@ -1050,7 +1081,7 @@ int freerdp_assistance_parse_file_buffer(rdpAssistanceFile* file, const char* bu
        return 1;
 }
 
-int freerdp_assistance_parse_file(rdpAssistanceFile* file, const char* name)
+int freerdp_assistance_parse_file(rdpAssistanceFile* file, const char* name, const char* password)
 {
        int status;
        BYTE* buffer;
@@ -1061,6 +1092,10 @@ int freerdp_assistance_parse_file(rdpAssistanceFile* file, const char* name)
        if (!name)
                return -1;
 
+       free(file->filename);
+       free(file->password);
+       file->filename = _strdup(name);
+       file->password = _strdup(password);
        fp = fopen(name, "r");
 
        if (!fp)
@@ -1103,34 +1138,43 @@ int freerdp_assistance_parse_file(rdpAssistanceFile* file, const char* name)
 
        buffer[fileSize] = '\0';
        buffer[fileSize + 1] = '\0';
-       status = freerdp_assistance_parse_file_buffer(file, (char*) buffer, fileSize);
+       status = freerdp_assistance_parse_file_buffer(file, (char*) buffer, fileSize, password);
        free(buffer);
        return status;
 }
 
-int freerdp_client_populate_settings_from_assistance_file(rdpAssistanceFile* file,
+BOOL freerdp_client_populate_settings_from_assistance_file(rdpAssistanceFile* file,
         rdpSettings* settings)
 {
        UINT32 i;
        freerdp_set_param_bool(settings, FreeRDP_RemoteAssistanceMode, TRUE);
 
        if (!file->RASessionId || !file->MachineAddress)
-               return -1;
+               return FALSE;
 
        if (freerdp_set_param_string(settings, FreeRDP_RemoteAssistanceSessionId, file->RASessionId) != 0)
-               return -1;
+               return FALSE;
 
        if (file->RCTicket &&
            (freerdp_set_param_string(settings, FreeRDP_RemoteAssistanceRCTicket, file->RCTicket) != 0))
-               return -1;
+               return FALSE;
 
-       if (file->PassStub &&
-           (freerdp_set_param_string(settings, FreeRDP_RemoteAssistancePassStub, file->PassStub) != 0))
-               return -1;
+       if (file->PassStub)
+       {
+               if (freerdp_set_param_string(settings, FreeRDP_RemoteAssistancePassStub, file->PassStub) != 0)
+                       return FALSE;
+       }
 
        if (freerdp_set_param_string(settings, FreeRDP_ServerHostname, file->MachineAddress) != 0)
-               return -1;
+               return FALSE;
+
+       if (freerdp_set_param_string(settings, FreeRDP_AssistanceFile, file->filename) != 0)
+               return FALSE;
 
+       if (freerdp_set_param_string(settings, FreeRDP_RemoteAssistancePassword, file->password) != 0)
+               return FALSE;
+
+       settings->RemoteAssistanceMode = TRUE;
        freerdp_set_param_uint32(settings, FreeRDP_ServerPort, file->MachinePort);
        freerdp_target_net_addresses_free(settings);
        settings->TargetNetAddressCount = file->MachineCount;
@@ -1141,7 +1185,7 @@ int freerdp_client_populate_settings_from_assistance_file(rdpAssistanceFile* fil
                settings->TargetNetPorts = (UINT32*) calloc(file->MachineCount, sizeof(UINT32));
 
                if (!settings->TargetNetAddresses || !settings->TargetNetPorts)
-                       return -1;
+                       return FALSE;
 
                for (i = 0; i < settings->TargetNetAddressCount; i++)
                {
@@ -1149,11 +1193,11 @@ int freerdp_client_populate_settings_from_assistance_file(rdpAssistanceFile* fil
                        settings->TargetNetPorts[i] = file->MachinePorts[i];
 
                        if (!settings->TargetNetAddresses[i])
-                               return -1;
+                               return FALSE;
                }
        }
 
-       return 1;
+       return TRUE;
 }
 
 rdpAssistanceFile* freerdp_assistance_file_new(void)
@@ -1168,6 +1212,8 @@ void freerdp_assistance_file_free(rdpAssistanceFile* file)
        if (!file)
                return;
 
+       free(file->filename);
+       free(file->password);
        free(file->Username);
        free(file->LHTicket);
        free(file->RCTicket);
@@ -1189,3 +1235,30 @@ void freerdp_assistance_file_free(rdpAssistanceFile* file)
        free(file->MachinePorts);
        free(file);
 }
+
+void freerdp_assistance_print_file(rdpAssistanceFile* file, wLog* log, DWORD level)
+{
+       WLog_Print(log, level, "Username: %s", file->Username);
+       WLog_Print(log, level, "LHTicket: %s", file->LHTicket);
+       WLog_Print(log, level, "RCTicket: %s", file->RCTicket);
+       WLog_Print(log, level, "RCTicketEncrypted: %"PRId32, file->RCTicketEncrypted);
+       WLog_Print(log, level, "PassStub: %s", file->PassStub);
+       WLog_Print(log, level, "DtStart: %"PRIu32, file->DtStart);
+       WLog_Print(log, level, "DtLength: %"PRIu32, file->DtLength);
+       WLog_Print(log, level, "LowSpeed: %"PRId32, file->LowSpeed);
+       WLog_Print(log, level, "RASessionId: %s", file->RASessionId);
+       WLog_Print(log, level, "RASpecificParams: %s", file->RASpecificParams);
+       WLog_Print(log, level, "MachineAddress: %s", file->MachineAddress);
+       WLog_Print(log, level, "MachinePort: %"PRIu32, file->MachinePort);
+}
+
+BOOL freerdp_assistance_get_encrypted_pass_stub(rdpAssistanceFile* file, const char** pwd,
+        size_t* size)
+{
+       if (!file || !pwd || !size)
+               return FALSE;
+
+       *pwd = (const char*)file->EncryptedPassStub;
+       *size = file->EncryptedPassStubLength;
+       return TRUE;
+}
index 0d3fdc6..8ac67d7 100644 (file)
@@ -8,58 +8,58 @@
 const char TEST_MSRC_INCIDENT_PASSWORD_TYPE1[] = "Password1";
 
 static const char TEST_MSRC_INCIDENT_FILE_TYPE1[] =
-"<?xml version=\"1.0\" encoding=\"Unicode\" ?>"
-"<UPLOADINFO TYPE=\"Escalated\">"
-"<UPLOADDATA "
-"USERNAME=\"Administrator\" "
-"RCTICKET=\"65538,1,10.0.3.105:3389;winxpsp3.contoso3.com:3389,*,"
-"rb+v0oPmEISmi8N2zK/vuhgul/ABqlDt6wW0VxMyxK8=,*,*,IuaRySSbPDNna4+2mKcsKxsbJFI=\""
-"RCTICKETENCRYPTED=\"1\" "
-"DtStart=\"1314905741\" "
-"DtLength=\"180\" "
-"PassStub=\"RT=0PvIndan52*\" "
-"L=\"0\" />"
-"</UPLOADINFO>";
+    "<?xml version=\"1.0\" encoding=\"Unicode\" ?>"
+    "<UPLOADINFO TYPE=\"Escalated\">"
+    "<UPLOADDATA "
+    "USERNAME=\"Administrator\" "
+    "RCTICKET=\"65538,1,10.0.3.105:3389;winxpsp3.contoso3.com:3389,*,"
+    "rb+v0oPmEISmi8N2zK/vuhgul/ABqlDt6wW0VxMyxK8=,*,*,IuaRySSbPDNna4+2mKcsKxsbJFI=\""
+    "RCTICKETENCRYPTED=\"1\" "
+    "DtStart=\"1314905741\" "
+    "DtLength=\"180\" "
+    "PassStub=\"RT=0PvIndan52*\" "
+    "L=\"0\" />"
+    "</UPLOADINFO>";
 
 const BYTE TEST_MSRC_INCIDENT_EXPERT_BLOB_TYPE1[32] =
-       "\x3C\x9C\xAE\x0B\xCE\x7A\xB1\x5C\x8A\xAC\x01\xD6\x76\x04\x5E\xDF"
-       "\x3F\xFA\xF0\x92\xE2\xDE\x36\x8A\x20\x17\xE6\x8A\x0D\xED\x7C\x90";
+    "\x3C\x9C\xAE\x0B\xCE\x7A\xB1\x5C\x8A\xAC\x01\xD6\x76\x04\x5E\xDF"
+    "\x3F\xFA\xF0\x92\xE2\xDE\x36\x8A\x20\x17\xE6\x8A\x0D\xED\x7C\x90";
 
 const char TEST_MSRC_INCIDENT_PASSWORD_TYPE2[] = "48BJQ853X3B4";
 
 static const char TEST_MSRC_INCIDENT_FILE_TYPE2[] =
-"<?xml version=\"1.0\"?>"
-"<UPLOADINFO TYPE=\"Escalated\">"
-"<UPLOADDATA USERNAME=\"awake\" "
-"LHTICKET=\""
-"20FCC407AA53E95F8505AB56D485D26835064B03AF86CDA326248FD304626AD4"
-"DBDBDFFE0C473228EFFF7A1E6CEB445BBEC429294BB6616BBB600854438DDFB5"
-"82FC377CF65A2060EB3221647643C9B29BF5EC320856180B34D1BE9827A528C7"
-"E8F0DCD53C8D38F974160FEE317458FAC9DBDBA7B972D21DF3BC5B1AF0E01878"
-"65F07A3B915618C03E6EAF843FC1185770A1208C29C836DBCA5A040CB276D3C4"
-"1DDE2FA8CA9627E5E74FA750A92C0E01AD6C3D1000A5B1479DEB899BF5BCD402"
-"CE3BB3BF104CE0286C3F985AA711943C88C5EEEEE86F35B63F68883A90ADBCFD"
-"CBBAE3EAB993EFD9148E1A21D092CE9498695943946236D65D20B4A38D724C61"
-"72319E38E19C04E98EBC03F56A4A190E971F8EAEBFE6B415A3A2D8F35F7BF785"
-"26B9BFAAB48D11BDD6C905EFE503D2265678E1EAD2F2F124E570667F04103180"
-"2F63587276C14E6A5AB436CE234F722CE7C9B5D244508F14C012E84A49FE6992"
-"3F30320ABB3641F1EFA66205F3EA709E7E1C3E6874BB9642486FB96D2730CDF4"
-"514AA738167F00FC13B2978AED1D6678413FDF62008B03DD729E36173BE02742"
-"B69CAD44938512D0F56335394759338AF6ADBCF39CE829116D97435085D05BB5"
-"9320A134698050DCDBE01305A6B4712FD6BD48958BD2DC497498FF35CAECC9A8"
-"2C97FD1A5B5EC4BAF5FFB75A1471B765C465B35A7C950019066BB219B391C6E9"
-"8AE8FD2038E774F36F226D9FB9A38BCC313785612165D1EF69D19E2B9CF6E0F7"
-"FE1ECCF00AB81F9E8B626363CA82FAC719A3B7D243325C9D6042B2488EC95B80"
-"A31273FF9B72FBBB86F946E6D3DF8816BE4533F0B547C8BC028309EA9784C1E6\" "
-"RCTICKET=\"65538,1,192.168.1.200:49230;169.254.6.170:49231,*,"
-"+ULZ6ifjoCa6cGPMLQiGHRPwkg6VyJqGwxMnO6GcelwUh9a6/FBq3It5ADSndmLL,"
-"*,*,BNRjdu97DyczQSRuMRrDWoue+HA=\" "
-"PassStub=\"WB^6HsrIaFmEpi\" "
-"RCTICKETENCRYPTED=\"1\" "
-"DtStart=\"1403972263\" "
-"DtLength=\"14400\" "
-"L=\"0\"/>"
-"</UPLOADINFO>";
+    "<?xml version=\"1.0\"?>"
+    "<UPLOADINFO TYPE=\"Escalated\">"
+    "<UPLOADDATA USERNAME=\"awake\" "
+    "LHTICKET=\""
+    "20FCC407AA53E95F8505AB56D485D26835064B03AF86CDA326248FD304626AD4"
+    "DBDBDFFE0C473228EFFF7A1E6CEB445BBEC429294BB6616BBB600854438DDFB5"
+    "82FC377CF65A2060EB3221647643C9B29BF5EC320856180B34D1BE9827A528C7"
+    "E8F0DCD53C8D38F974160FEE317458FAC9DBDBA7B972D21DF3BC5B1AF0E01878"
+    "65F07A3B915618C03E6EAF843FC1185770A1208C29C836DBCA5A040CB276D3C4"
+    "1DDE2FA8CA9627E5E74FA750A92C0E01AD6C3D1000A5B1479DEB899BF5BCD402"
+    "CE3BB3BF104CE0286C3F985AA711943C88C5EEEEE86F35B63F68883A90ADBCFD"
+    "CBBAE3EAB993EFD9148E1A21D092CE9498695943946236D65D20B4A38D724C61"
+    "72319E38E19C04E98EBC03F56A4A190E971F8EAEBFE6B415A3A2D8F35F7BF785"
+    "26B9BFAAB48D11BDD6C905EFE503D2265678E1EAD2F2F124E570667F04103180"
+    "2F63587276C14E6A5AB436CE234F722CE7C9B5D244508F14C012E84A49FE6992"
+    "3F30320ABB3641F1EFA66205F3EA709E7E1C3E6874BB9642486FB96D2730CDF4"
+    "514AA738167F00FC13B2978AED1D6678413FDF62008B03DD729E36173BE02742"
+    "B69CAD44938512D0F56335394759338AF6ADBCF39CE829116D97435085D05BB5"
+    "9320A134698050DCDBE01305A6B4712FD6BD48958BD2DC497498FF35CAECC9A8"
+    "2C97FD1A5B5EC4BAF5FFB75A1471B765C465B35A7C950019066BB219B391C6E9"
+    "8AE8FD2038E774F36F226D9FB9A38BCC313785612165D1EF69D19E2B9CF6E0F7"
+    "FE1ECCF00AB81F9E8B626363CA82FAC719A3B7D243325C9D6042B2488EC95B80"
+    "A31273FF9B72FBBB86F946E6D3DF8816BE4533F0B547C8BC028309EA9784C1E6\" "
+    "RCTICKET=\"65538,1,192.168.1.200:49230;169.254.6.170:49231,*,"
+    "+ULZ6ifjoCa6cGPMLQiGHRPwkg6VyJqGwxMnO6GcelwUh9a6/FBq3It5ADSndmLL,"
+    "*,*,BNRjdu97DyczQSRuMRrDWoue+HA=\" "
+    "PassStub=\"WB^6HsrIaFmEpi\" "
+    "RCTICKETENCRYPTED=\"1\" "
+    "DtStart=\"1403972263\" "
+    "DtLength=\"14400\" "
+    "L=\"0\"/>"
+    "</UPLOADINFO>";
 
 /**
  * Decrypted Connection String 2:
@@ -77,105 +77,68 @@ static const char TEST_MSRC_INCIDENT_FILE_TYPE2[] =
  * </E>
  */
 
-int test_msrsc_incident_file_type1()
+static int test_msrsc_incident_file_type1(void)
 {
        int status;
        char* pass;
        char* expertBlob;
+       const char* EncryptedPassStub;
+       size_t EncryptedPassStubLength;
        rdpAssistanceFile* file;
-
        file = freerdp_assistance_file_new();
 
        if (!file)
                return -1;
 
        status = freerdp_assistance_parse_file_buffer(file,
-                       TEST_MSRC_INCIDENT_FILE_TYPE1, sizeof(TEST_MSRC_INCIDENT_FILE_TYPE1));
-
+                TEST_MSRC_INCIDENT_FILE_TYPE1, sizeof(TEST_MSRC_INCIDENT_FILE_TYPE1),
+                TEST_MSRC_INCIDENT_PASSWORD_TYPE1);
        printf("freerdp_assistance_parse_file_buffer: %d\n", status);
 
        if (status < 0)
                return -1;
 
-       printf("Username: %s\n", file->Username);
-       printf("LHTicket: %s\n", file->LHTicket);
-       printf("RCTicket: %s\n", file->RCTicket);
-       printf("RCTicketEncrypted: %"PRId32"\n", file->RCTicketEncrypted);
-       printf("PassStub: %s\n", file->PassStub);
-       printf("DtStart: %"PRIu32"\n", file->DtStart);
-       printf("DtLength: %"PRIu32"\n", file->DtLength);
-       printf("LowSpeed: %"PRId32"\n", file->LowSpeed);
-
-       printf("RASessionId: %s\n", file->RASessionId);
-       printf("RASpecificParams: %s\n", file->RASpecificParams);
-       printf("MachineAddress: %s\n", file->MachineAddress);
-       printf("MachinePort: %"PRIu32"\n", file->MachinePort);
+       freerdp_assistance_print_file(file, WLog_Get("foo"), WLOG_INFO);
 
-       status = freerdp_assistance_decrypt(file, TEST_MSRC_INCIDENT_PASSWORD_TYPE1);
-
-       printf("freerdp_assistance_decrypt: %d\n", status);
-
-       if (status < 0)
+       if (!freerdp_assistance_get_encrypted_pass_stub(file, &EncryptedPassStub, &EncryptedPassStubLength))
                return -1;
 
-       pass = freerdp_assistance_bin_to_hex_string(file->EncryptedPassStub, file->EncryptedPassStubLength);
+       pass = freerdp_assistance_bin_to_hex_string(EncryptedPassStub, EncryptedPassStubLength);
 
        if (!pass)
                return -1;
 
        expertBlob = freerdp_assistance_construct_expert_blob("Edgar Olougouna", pass);
-
        freerdp_assistance_file_free(file);
-
        free(pass);
        free(expertBlob);
-
        return 0;
 }
 
-int test_msrsc_incident_file_type2()
+static int test_msrsc_incident_file_type2(void)
 {
        int status;
        rdpAssistanceFile* file;
-
        file = freerdp_assistance_file_new();
 
        if (!file)
                return -1;
 
        status = freerdp_assistance_parse_file_buffer(file,
-                       TEST_MSRC_INCIDENT_FILE_TYPE2, sizeof(TEST_MSRC_INCIDENT_FILE_TYPE2));
-
+                TEST_MSRC_INCIDENT_FILE_TYPE2, sizeof(TEST_MSRC_INCIDENT_FILE_TYPE2), NULL);
        printf("freerdp_assistance_parse_file_buffer: %d\n", status);
 
        if (status < 0)
                return -1;
 
-       printf("Username: %s\n", file->Username);
-       printf("LHTicket: %s\n", file->LHTicket);
-       printf("RCTicket: %s\n", file->RCTicket);
-       printf("RCTicketEncrypted: %"PRId32"\n", file->RCTicketEncrypted);
-       printf("PassStub: %s\n", file->PassStub);
-       printf("DtStart: %"PRIu32"\n", file->DtStart);
-       printf("DtLength: %"PRIu32"\n", file->DtLength);
-       printf("LowSpeed: %"PRId32"\n", file->LowSpeed);
-
-       printf("RASessionId: %s\n", file->RASessionId);
-       printf("RASpecificParams: %s\n", file->RASpecificParams);
-       printf("MachineAddress: %s\n", file->MachineAddress);
-       printf("MachinePort: %"PRIu32"\n", file->MachinePort);
-
+       freerdp_assistance_print_file(file, WLog_Get("foo"), WLOG_INFO);
        status = freerdp_assistance_decrypt(file, TEST_MSRC_INCIDENT_PASSWORD_TYPE2);
-
        printf("freerdp_assistance_decrypt: %d\n", status);
 
        if (status < 0)
                return -1;
 
-       printf("ConnectionString2: %s\n", file->ConnectionString2);
-
        freerdp_assistance_file_free(file);
-
        return 0;
 }