From b60eff8e42edd011fdf5fd2b6aa34880aae2c733 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 30 Jun 2014 12:51:27 -0400 Subject: [PATCH] channels/remdesk: start sending authentication data --- channels/remdesk/client/CMakeLists.txt | 5 + channels/remdesk/client/remdesk_main.c | 77 ++++++- channels/remdesk/client/remdesk_main.h | 5 + client/common/client.c | 6 +- client/common/cmdline.c | 26 +-- include/freerdp/assistance.h | 16 +- include/freerdp/settings.h | 8 +- libfreerdp/common/assistance.c | 194 ++++++++++-------- libfreerdp/common/settings.c | 27 +++ libfreerdp/common/test/TestCommonAssistance.c | 36 ++-- libfreerdp/core/settings.c | 3 + 11 files changed, 270 insertions(+), 133 deletions(-) diff --git a/channels/remdesk/client/CMakeLists.txt b/channels/remdesk/client/CMakeLists.txt index 9d8323634..bcc67307b 100644 --- a/channels/remdesk/client/CMakeLists.txt +++ b/channels/remdesk/client/CMakeLists.txt @@ -25,6 +25,11 @@ add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "") +set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS + MONOLITHIC ${MONOLITHIC_BUILD} + MODULE freerdp + MODULES freerdp-common) + set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MONOLITHIC ${MONOLITHIC_BUILD} MODULE winpr diff --git a/channels/remdesk/client/remdesk_main.c b/channels/remdesk/client/remdesk_main.c index 4c41f64a2..724ec0fee 100644 --- a/channels/remdesk/client/remdesk_main.c +++ b/channels/remdesk/client/remdesk_main.c @@ -24,6 +24,8 @@ #include #include +#include + #include #include "remdesk_main.h" @@ -42,6 +44,9 @@ int remdesk_virtual_channel_write(remdeskPlugin* remdesk, wStream* s) if (!remdesk) return -1; + printf("RemdeskWrite (%d)\n", Stream_Length(s)); + winpr_HexDump(Stream_Buffer(s), Stream_Length(s)); + status = remdesk->channelEntryPoints.pVirtualChannelWrite(remdesk->OpenHandle, Stream_Buffer(s), (UINT32) Stream_Length(s), s); @@ -54,6 +59,48 @@ int remdesk_virtual_channel_write(remdeskPlugin* remdesk, wStream* s) return 1; } +int remdesk_generate_expert_blob(remdeskPlugin* remdesk) +{ + char* name; + char* pass; + char* password; + rdpSettings* settings = remdesk->settings; + + if (remdesk->ExpertBlob) + return 1; + + if (settings->RemoteAssistancePassword) + password = settings->RemoteAssistancePassword; + else + password = settings->Password; + + if (!password) + return -1; + + name = settings->Username; + + if (!name) + name = "Expert"; + + remdesk->EncryptedPassStub = freerdp_assistance_encrypt_pass_stub(password, + settings->RemoteAssistancePassStub, &(remdesk->EncryptedPassStubSize)); + + if (!remdesk->EncryptedPassStub) + return -1; + + pass = freerdp_assistance_bin_to_hex_string(remdesk->EncryptedPassStub, remdesk->EncryptedPassStubSize); + + if (!pass) + return -1; + + remdesk->ExpertBlob = freerdp_assistance_construct_expert_blob(name, pass); + + if (!remdesk->ExpertBlob) + return -1; + + return 1; +} + int remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header) { int status; @@ -91,25 +138,23 @@ int remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header) int remdesk_write_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header) { - int status; + int index; UINT32 ChannelNameLen; WCHAR ChannelNameW[32]; - WCHAR* pChannelName = NULL; ZeroMemory(ChannelNameW, sizeof(ChannelNameW)); - pChannelName = (WCHAR*) ChannelNameW; - status = ConvertToUnicode(CP_UTF8, 0, header->ChannelName, -1, &pChannelName, 32); + for (index = 0; index < 32; index++) + { + ChannelNameW[index] = (WCHAR) header->ChannelName[index]; + } - if (status <= 0) - return -1; - - ChannelNameLen = (status + 1) * 2; + ChannelNameLen = strlen(header->ChannelName) * 2; Stream_Write_UINT32(s, ChannelNameLen); /* ChannelNameLen (4 bytes) */ Stream_Write_UINT32(s, header->DataLength); /* DataLen (4 bytes) */ - Stream_Write(s, pChannelName, ChannelNameLen); /* ChannelName (variable) */ + Stream_Write(s, ChannelNameW, ChannelNameLen); /* ChannelName (variable) */ return 1; } @@ -203,8 +248,13 @@ int remdesk_send_ctl_authenticate_pdu(remdeskPlugin* remdesk) WCHAR* raConnectionStringW = NULL; REMDESK_CTL_AUTHENTICATE_PDU pdu; - pdu.expertBlob = NULL; - pdu.raConnectionString = NULL; + status = remdesk_generate_expert_blob(remdesk); + + if (status < 0) + return -1; + + pdu.expertBlob = remdesk->ExpertBlob; + pdu.raConnectionString = remdesk->settings->RemoteAssistanceRCTicket; status = ConvertToUnicode(CP_UTF8, 0, pdu.raConnectionString, -1, &raConnectionStringW, 0); @@ -339,6 +389,9 @@ int remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEA if (status >= 0) status = remdesk_send_ctl_version_info_pdu(remdesk); + if (status >= 0) + status = remdesk_send_ctl_authenticate_pdu(remdesk); + break; case REMDESK_CTL_ISCONNECTED: @@ -413,6 +466,8 @@ int remdesk_process_receive(remdeskPlugin* remdesk, wStream* s) static void remdesk_process_connect(remdeskPlugin* remdesk) { printf("RemdeskProcessConnect\n"); + + remdesk->settings = (rdpSettings*) remdesk->channelEntryPoints.pExtendedData; } /****************************************************************************************/ diff --git a/channels/remdesk/client/remdesk_main.h b/channels/remdesk/client/remdesk_main.h index 0a2261e34..031353be5 100644 --- a/channels/remdesk/client/remdesk_main.h +++ b/channels/remdesk/client/remdesk_main.h @@ -29,6 +29,7 @@ #include #include #include +#include #include @@ -42,8 +43,12 @@ struct remdesk_plugin void* InitHandle; DWORD OpenHandle; wMessagePipe* MsgPipe; + rdpSettings* settings; UINT32 Version; + char* ExpertBlob; + BYTE* EncryptedPassStub; + int EncryptedPassStubSize; }; typedef struct remdesk_plugin remdeskPlugin; diff --git a/client/common/client.c b/client/common/client.c index b3b5ff391..c3fea6fb2 100644 --- a/client/common/client.c +++ b/client/common/client.c @@ -179,12 +179,12 @@ int freerdp_client_settings_parse_assistance_file(rdpSettings* settings, const c int status; rdpAssistanceFile* file; - file = freerdp_client_assistance_file_new(); + file = freerdp_assistance_file_new(); if (!file) return -1; - status = freerdp_client_assistance_parse_file(file, filename); + status = freerdp_assistance_parse_file(file, filename); if (status < 0) return -1; @@ -194,7 +194,7 @@ int freerdp_client_settings_parse_assistance_file(rdpSettings* settings, const c if (status < 0) return -1; - freerdp_client_assistance_file_free(file); + freerdp_assistance_file_free(file); return 0; } diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 71641ea6b..392f39da2 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -156,7 +156,7 @@ COMMAND_LINE_ARGUMENT_A args[] = { "print-reconnect-cookie", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Print base64 reconnect cookie after connecting" }, { "heartbeat", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Support heartbeat PDUs" }, { "multitransport", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Support multitransport protocol" }, - { "assistance", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Remote assistance mode" }, + { "assistance", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Remote assistance password" }, { NULL, 0, NULL, NULL, NULL, -1, NULL, NULL } }; @@ -1859,7 +1859,10 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, } CommandLineSwitchCase(arg, "assistance") { - settings->RemoteAssistanceMode = arg->Value ? TRUE : FALSE; + settings->RemoteAssistanceMode = TRUE; + settings->RemoteAssistancePassword = _strdup(arg->Value); + + printf("AssistancePassword: %s settings: %p\n", settings->RemoteAssistancePassword, settings); } CommandLineSwitchDefault(arg) { @@ -2041,23 +2044,8 @@ int freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings) if (settings->RemoteAssistanceMode) { - if (!freerdp_static_channel_collection_find(settings, "encomsp")) - { - char* params[1]; - - params[0] = "encomsp"; - - freerdp_client_add_static_channel(settings, 1, (char**) params); - } - - if (!freerdp_static_channel_collection_find(settings, "remdesk")) - { - char* params[1]; - - params[0] = "remdesk"; - - freerdp_client_add_static_channel(settings, 1, (char**) params); - } + freerdp_client_load_static_channel_addin(channels, settings, "encomsp", settings); + freerdp_client_load_static_channel_addin(channels, settings, "remdesk", settings); } for (index = 0; index < settings->StaticChannelCount; index++) diff --git a/include/freerdp/assistance.h b/include/freerdp/assistance.h index 00bd33a35..a2fe426d6 100644 --- a/include/freerdp/assistance.h +++ b/include/freerdp/assistance.h @@ -56,14 +56,20 @@ typedef struct rdp_assistance_file rdpAssistanceFile; extern "C" { #endif -FREERDP_API int freerdp_client_assistance_parse_file_buffer(rdpAssistanceFile* file, const char* buffer, size_t size); -FREERDP_API int freerdp_client_assistance_parse_file(rdpAssistanceFile* file, const char* name); -FREERDP_API int freerdp_client_assistance_decrypt(rdpAssistanceFile* file, const char* password); +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 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 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_client_populate_settings_from_assistance_file(rdpAssistanceFile* file, rdpSettings* settings); -FREERDP_API rdpAssistanceFile* freerdp_client_assistance_file_new(); -FREERDP_API void freerdp_client_assistance_file_free(rdpAssistanceFile* file); +FREERDP_API rdpAssistanceFile* freerdp_assistance_file_new(); +FREERDP_API void freerdp_assistance_file_free(rdpAssistanceFile* file); #ifdef __cplusplus } diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index 2695a70cc..07fc0d354 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -587,6 +587,9 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL; #define FreeRDP_AllowDesktopComposition 968 #define FreeRDP_RemoteAssistanceMode 1024 #define FreeRDP_RemoteAssistanceSessionId 1025 +#define FreeRDP_RemoteAssistancePassStub 1026 +#define FreeRDP_RemoteAssistancePassword 1027 +#define FreeRDP_RemoteAssistanceRCTicket 1028 #define FreeRDP_TlsSecurity 1088 #define FreeRDP_NlaSecurity 1089 #define FreeRDP_RdpSecurity 1090 @@ -942,7 +945,10 @@ struct rdp_settings /* Remote Assistance */ ALIGN64 BOOL RemoteAssistanceMode; /* 1024 */ ALIGN64 char* RemoteAssistanceSessionId; /* 1025 */ - UINT64 padding1088[1088 - 1026]; /* 1026 */ + ALIGN64 char* RemoteAssistancePassStub; /* 1026 */ + ALIGN64 char* RemoteAssistancePassword; /* 1027 */ + ALIGN64 char* RemoteAssistanceRCTicket; /* 1028 */ + UINT64 padding1088[1088 - 1029]; /* 1029 */ /** * X.224 Connection Request/Confirm diff --git a/libfreerdp/common/assistance.c b/libfreerdp/common/assistance.c index a9103a502..87e602d4d 100644 --- a/libfreerdp/common/assistance.c +++ b/libfreerdp/common/assistance.c @@ -75,7 +75,7 @@ * Use the first n bytes of the result of step 5 as the derived key. */ -int freerdp_client_assistance_crypt_derive_key_sha1(BYTE* hash, int hashLength, BYTE* key, int keyLength) +int freerdp_assistance_crypt_derive_key_sha1(BYTE* hash, int hashLength, BYTE* key, int keyLength) { int i; BYTE* buffer; @@ -112,7 +112,7 @@ int freerdp_client_assistance_crypt_derive_key_sha1(BYTE* hash, int hashLength, return 1; } -int freerdp_client_assistance_parse_connection_string1(rdpAssistanceFile* file) +int freerdp_assistance_parse_connection_string1(rdpAssistanceFile* file) { int i; char* p; @@ -223,7 +223,7 @@ int freerdp_client_assistance_parse_connection_string1(rdpAssistanceFile* file) * */ -int freerdp_client_assistance_parse_connection_string2(rdpAssistanceFile* file) +int freerdp_assistance_parse_connection_string2(rdpAssistanceFile* file) { char* p; char* q; @@ -303,80 +303,79 @@ int freerdp_client_assistance_parse_connection_string2(rdpAssistanceFile* file) return 1; } -int freerdp_client_assistance_decrypt1(rdpAssistanceFile* file, const char* password) +char* freerdp_assistance_construct_expert_blob(const char* name, const char* pass) +{ + int size; + int nameLength; + int passLength; + char* ExpertBlob = NULL; + + if (!name || !pass) + return NULL; + + nameLength = strlen(name) + strlen("NAME="); + passLength = strlen(pass) + strlen("PASS="); + + size = nameLength + passLength + 64; + ExpertBlob = (char*) calloc(1, size); + + if (!ExpertBlob) + return NULL; + + sprintf_s(ExpertBlob, size, "%d;NAME=%s%d;PASS=%s", + nameLength, name, passLength, pass); + + return ExpertBlob; +} + +BYTE* freerdp_assistance_encrypt_pass_stub(const char* password, const char* passStub, int* pEncryptedSize) { int status; MD5_CTX md5Ctx; int cbPasswordW; int cbPassStubW; + int EncryptedSize; + BYTE PasswordHash[16]; EVP_CIPHER_CTX rc4Ctx; - BYTE* PlainBlob = NULL; - WCHAR* PasswordW = NULL; - WCHAR* PassStubW = NULL; BYTE *pbIn, *pbOut; int cbOut, cbIn, cbFinal; - BYTE DerivedKey[16]; - BYTE InitializationVector[16]; - BYTE PasswordHash[16]; - - /** - * PROV_RSA_FULL provider - * CALG_MD5 hashing - * CALG_RC4 encryption - * Key Length: 40 bits - * Salt Length: 88 bits - */ + WCHAR* PasswordW = NULL; + WCHAR* PassStubW = NULL; status = ConvertToUnicode(CP_UTF8, 0, password, -1, &PasswordW, 0); if (status <= 0) - return -1; + return NULL; cbPasswordW = (status - 1) * 2; - printf("PasswordW (%d)\n", cbPasswordW); - winpr_HexDump((BYTE*) PasswordW, cbPasswordW); - MD5_Init(&md5Ctx); MD5_Update(&md5Ctx, PasswordW, cbPasswordW); MD5_Final((void*) PasswordHash, &md5Ctx); - printf("PasswordHash (%s):\n", password); - winpr_HexDump(PasswordHash, sizeof(PasswordHash)); - - CopyMemory(DerivedKey, PasswordHash, 16); - - printf("DerivedKey (%d):\n", sizeof(DerivedKey)); - winpr_HexDump(DerivedKey, sizeof(DerivedKey)); - - ZeroMemory(InitializationVector, sizeof(InitializationVector)); - - status = ConvertToUnicode(CP_UTF8, 0, file->PassStub, -1, &PassStubW, 0); + status = ConvertToUnicode(CP_UTF8, 0, passStub, -1, &PassStubW, 0); if (status <= 0) - return -1; + return NULL; cbPassStubW = (status - 1) * 2; - printf("PassStubW (%d)\n", cbPassStubW); - winpr_HexDump((BYTE*) PassStubW, cbPassStubW); + EncryptedSize = cbPassStubW + 4; - file->EncryptedPassStubLength = cbPassStubW + 4; + pbIn = (BYTE*) calloc(1, EncryptedSize); + pbOut = (BYTE*) calloc(1, EncryptedSize); - PlainBlob = (BYTE*) calloc(1, file->EncryptedPassStubLength); - file->EncryptedPassStub = (BYTE*) calloc(1, file->EncryptedPassStubLength); + if (!pbIn) + return NULL; - if (!PlainBlob) - return -1; + if (!EncryptedSize) + return NULL; - if (!file->EncryptedPassStubLength) - return -1; + *((UINT32*) pbIn) = cbPassStubW; + CopyMemory(&pbIn[4], PassStubW, cbPassStubW); - *((UINT32*) PlainBlob) = cbPassStubW; - CopyMemory(&PlainBlob[4], PassStubW, cbPassStubW); - - printf("PlainBlob (%d)\n", file->EncryptedPassStubLength); - winpr_HexDump(PlainBlob, file->EncryptedPassStubLength); + printf("PlainBlob (%d)\n", EncryptedSize); + winpr_HexDump(pbIn, EncryptedSize); EVP_CIPHER_CTX_init(&rc4Ctx); @@ -385,30 +384,26 @@ int freerdp_client_assistance_decrypt1(rdpAssistanceFile* file, const char* pass if (!status) { fprintf(stderr, "EVP_CipherInit_ex failure\n"); - return -1; + return NULL; } - EVP_CIPHER_CTX_set_padding(&rc4Ctx, 0); - - status = EVP_EncryptInit_ex(&rc4Ctx, NULL, NULL, DerivedKey, InitializationVector); + status = EVP_EncryptInit_ex(&rc4Ctx, NULL, NULL, PasswordHash, NULL); if (!status) { fprintf(stderr, "EVP_CipherInit_ex failure\n"); - return -1; + return NULL; } cbOut = cbFinal = 0; - cbIn = file->EncryptedPassStubLength; - pbOut = file->EncryptedPassStub; - pbIn = PlainBlob; + cbIn = EncryptedSize; status = EVP_EncryptUpdate(&rc4Ctx, pbOut, &cbOut, pbIn, cbIn); if (!status) { fprintf(stderr, "EVP_CipherUpdate failure\n"); - return -1; + return NULL; } status = EVP_EncryptFinal_ex(&rc4Ctx, pbOut + cbOut, &cbFinal); @@ -416,22 +411,24 @@ int freerdp_client_assistance_decrypt1(rdpAssistanceFile* file, const char* pass if (!status) { fprintf(stderr, "EVP_CipherFinal_ex failure\n"); - return -1; + return NULL; } EVP_CIPHER_CTX_cleanup(&rc4Ctx); - printf("EncryptedPassStub (%d):\n", file->EncryptedPassStubLength); - winpr_HexDump(file->EncryptedPassStub, file->EncryptedPassStubLength); + printf("EncryptedBlob (%d):\n", EncryptedSize); + winpr_HexDump(pbOut, EncryptedSize); - free(PlainBlob); + free(pbIn); free(PasswordW); free(PassStubW); - return 1; + *pEncryptedSize = EncryptedSize; + + return pbOut; } -int freerdp_client_assistance_decrypt2(rdpAssistanceFile* file, const char* password) +int freerdp_assistance_decrypt2(rdpAssistanceFile* file, const char* password) { int status; SHA_CTX shaCtx; @@ -457,7 +454,7 @@ int freerdp_client_assistance_decrypt2(rdpAssistanceFile* file, const char* pass SHA1_Update(&shaCtx, PasswordW, cbPasswordW); SHA1_Final((void*) PasswordHash, &shaCtx); - status = freerdp_client_assistance_crypt_derive_key_sha1(PasswordHash, sizeof(PasswordHash), + status = freerdp_assistance_crypt_derive_key_sha1(PasswordHash, sizeof(PasswordHash), DerivedKey, sizeof(DerivedKey)); if (status < 0) @@ -518,35 +515,39 @@ int freerdp_client_assistance_decrypt2(rdpAssistanceFile* file, const char* pass free(PasswordW); free(pbOut); - status = freerdp_client_assistance_parse_connection_string2(file); + status = freerdp_assistance_parse_connection_string2(file); - printf("freerdp_client_assistance_parse_connection_string2: %d\n", status); + printf("freerdp_assistance_parse_connection_string2: %d\n", status); return 1; } -int freerdp_client_assistance_decrypt(rdpAssistanceFile* file, const char* password) +int freerdp_assistance_decrypt(rdpAssistanceFile* file, const char* password) { - int status; + int status = 1; - status = freerdp_client_assistance_decrypt1(file, password); + file->EncryptedPassStub = freerdp_assistance_encrypt_pass_stub(password, + file->PassStub, &file->EncryptedPassStubLength); + + if (!file->EncryptedPassStub) + return -1; if (file->Type > 1) { - status = freerdp_client_assistance_decrypt2(file, password); + status = freerdp_assistance_decrypt2(file, password); } return status; } -BYTE* freerdp_client_assistance_parse_hex_string(const char* hexStr, int* size) +BYTE* freerdp_assistance_hex_string_to_bin(const char* str, int* size) { char c; int length; BYTE* buffer; int i, ln, hn; - length = strlen(hexStr); + length = strlen(str); if ((length % 2) != 0) return NULL; @@ -563,7 +564,7 @@ BYTE* freerdp_client_assistance_parse_hex_string(const char* hexStr, int* size) { hn = ln = 0; - c = hexStr[(i * 2) + 0]; + c = str[(i * 2) + 0]; if ((c >= '0') && (c <= '9')) hn = c - '0'; @@ -572,7 +573,7 @@ BYTE* freerdp_client_assistance_parse_hex_string(const char* hexStr, int* size) else if ((c >= 'A') && (c <= 'F')) hn = (c - 'A') + 10; - c = hexStr[(i * 2) + 1]; + c = str[(i * 2) + 1]; if ((c >= '0') && (c <= '9')) ln = c - '0'; @@ -587,7 +588,30 @@ BYTE* freerdp_client_assistance_parse_hex_string(const char* hexStr, int* size) return buffer; } -int freerdp_client_assistance_parse_file_buffer(rdpAssistanceFile* file, const char* buffer, size_t size) +char* freerdp_assistance_bin_to_hex_string(const BYTE* data, int size) +{ + int i; + char* p; + int ln, hn; + char bin2hex[] = "0123456789ABCDEF"; + + p = (char*) malloc((size + 1) * 2); + + for (i = 0; i < size; i++) + { + ln = data[i] & 0xF; + hn = (data[i] >> 4) & 0xF; + + p[i * 2] = bin2hex[hn]; + p[(i * 2) + 1] = bin2hex[ln]; + } + + p[size * 2] = '\0'; + + return p; +} + +int freerdp_assistance_parse_file_buffer(rdpAssistanceFile* file, const char* buffer, size_t size) { char* p; char* q; @@ -801,22 +825,22 @@ int freerdp_client_assistance_parse_file_buffer(rdpAssistanceFile* file, const c if (file->LHTicket) { - file->EncryptedLHTicket = freerdp_client_assistance_parse_hex_string(file->LHTicket, + file->EncryptedLHTicket = freerdp_assistance_hex_string_to_bin(file->LHTicket, &file->EncryptedLHTicketLength); } - status = freerdp_client_assistance_parse_connection_string1(file); + status = freerdp_assistance_parse_connection_string1(file); if (status < 0) { - fprintf(stderr, "freerdp_client_assistance_parse_connection_string1 failure: %d\n", status); + fprintf(stderr, "freerdp_assistance_parse_connection_string1 failure: %d\n", status); return -1; } return 1; } -int freerdp_client_assistance_parse_file(rdpAssistanceFile* file, const char* name) +int freerdp_assistance_parse_file(rdpAssistanceFile* file, const char* name) { int status; BYTE* buffer; @@ -859,7 +883,7 @@ int freerdp_client_assistance_parse_file(rdpAssistanceFile* file, const char* na buffer[fileSize] = '\0'; buffer[fileSize + 1] = '\0'; - status = freerdp_client_assistance_parse_file_buffer(file, (char*) buffer, fileSize); + status = freerdp_assistance_parse_file_buffer(file, (char*) buffer, fileSize); free(buffer); @@ -875,6 +899,12 @@ int freerdp_client_populate_settings_from_assistance_file(rdpAssistanceFile* fil freerdp_set_param_string(settings, FreeRDP_RemoteAssistanceSessionId, file->RASessionId); + if (file->RCTicket) + freerdp_set_param_string(settings, FreeRDP_RemoteAssistanceRCTicket, file->RCTicket); + + if (file->PassStub) + freerdp_set_param_string(settings, FreeRDP_RemoteAssistancePassStub, file->PassStub); + if (!file->MachineAddress) return -1; @@ -884,7 +914,7 @@ int freerdp_client_populate_settings_from_assistance_file(rdpAssistanceFile* fil return 1; } -rdpAssistanceFile* freerdp_client_assistance_file_new() +rdpAssistanceFile* freerdp_assistance_file_new() { rdpAssistanceFile* file; @@ -898,7 +928,7 @@ rdpAssistanceFile* freerdp_client_assistance_file_new() return file; } -void freerdp_client_assistance_file_free(rdpAssistanceFile* file) +void freerdp_assistance_file_free(rdpAssistanceFile* file) { if (!file) return; diff --git a/libfreerdp/common/settings.c b/libfreerdp/common/settings.c index 12fe064a6..97df29b15 100644 --- a/libfreerdp/common/settings.c +++ b/libfreerdp/common/settings.c @@ -2380,6 +2380,18 @@ char* freerdp_get_param_string(rdpSettings* settings, int id) return settings->RemoteAssistanceSessionId; break; + case FreeRDP_RemoteAssistancePassStub: + return settings->RemoteAssistancePassStub; + break; + + case FreeRDP_RemoteAssistancePassword: + return settings->RemoteAssistancePassword; + break; + + case FreeRDP_RemoteAssistanceRCTicket: + return settings->RemoteAssistanceRCTicket; + break; + case FreeRDP_AuthenticationServiceClass: return settings->AuthenticationServiceClass; break; @@ -2574,6 +2586,21 @@ int freerdp_set_param_string(rdpSettings* settings, int id, const char* param) settings->RemoteAssistanceSessionId = _strdup(param); break; + case FreeRDP_RemoteAssistancePassStub: + free(settings->RemoteAssistancePassStub); + settings->RemoteAssistancePassStub = _strdup(param); + break; + + case FreeRDP_RemoteAssistancePassword: + free(settings->RemoteAssistancePassword); + settings->RemoteAssistancePassword = _strdup(param); + break; + + case FreeRDP_RemoteAssistanceRCTicket: + free(settings->RemoteAssistanceRCTicket); + settings->RemoteAssistanceRCTicket = _strdup(param); + break; + case FreeRDP_AuthenticationServiceClass: free(settings->AuthenticationServiceClass); settings->AuthenticationServiceClass = _strdup(param); diff --git a/libfreerdp/common/test/TestCommonAssistance.c b/libfreerdp/common/test/TestCommonAssistance.c index 697d3e303..411152508 100644 --- a/libfreerdp/common/test/TestCommonAssistance.c +++ b/libfreerdp/common/test/TestCommonAssistance.c @@ -79,14 +79,16 @@ static const char* TEST_MSRC_INCIDENT_FILE_TYPE2 = int test_msrsc_incident_file_type1() { int status; + char* pass; + char* expertBlob; rdpAssistanceFile* file; - file = freerdp_client_assistance_file_new(); + file = freerdp_assistance_file_new(); - status = freerdp_client_assistance_parse_file_buffer(file, + status = freerdp_assistance_parse_file_buffer(file, TEST_MSRC_INCIDENT_FILE_TYPE1, sizeof(TEST_MSRC_INCIDENT_FILE_TYPE1)); - printf("freerdp_client_assistance_parse_file_buffer: %d\n", status); + printf("freerdp_assistance_parse_file_buffer: %d\n", status); if (status < 0) return -1; @@ -105,14 +107,24 @@ int test_msrsc_incident_file_type1() printf("MachineAddress: %s\n", file->MachineAddress); printf("MachinePort: %d\n", (int) file->MachinePort); - status = freerdp_client_assistance_decrypt(file, TEST_MSRC_INCIDENT_PASSWORD_TYPE1); + status = freerdp_assistance_decrypt(file, TEST_MSRC_INCIDENT_PASSWORD_TYPE1); - printf("freerdp_client_assistance_decrypt: %d\n", status); + printf("freerdp_assistance_decrypt: %d\n", status); if (status < 0) return -1; - freerdp_client_assistance_file_free(file); + pass = freerdp_assistance_bin_to_hex_string(file->EncryptedPassStub, file->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; } @@ -122,12 +134,12 @@ int test_msrsc_incident_file_type2() int status; rdpAssistanceFile* file; - file = freerdp_client_assistance_file_new(); + file = freerdp_assistance_file_new(); - status = freerdp_client_assistance_parse_file_buffer(file, + status = freerdp_assistance_parse_file_buffer(file, TEST_MSRC_INCIDENT_FILE_TYPE2, sizeof(TEST_MSRC_INCIDENT_FILE_TYPE2)); - printf("freerdp_client_assistance_parse_file_buffer: %d\n", status); + printf("freerdp_assistance_parse_file_buffer: %d\n", status); if (status < 0) return -1; @@ -146,16 +158,16 @@ int test_msrsc_incident_file_type2() printf("MachineAddress: %s\n", file->MachineAddress); printf("MachinePort: %d\n", (int) file->MachinePort); - status = freerdp_client_assistance_decrypt(file, TEST_MSRC_INCIDENT_PASSWORD_TYPE2); + status = freerdp_assistance_decrypt(file, TEST_MSRC_INCIDENT_PASSWORD_TYPE2); - printf("freerdp_client_assistance_decrypt: %d\n", status); + printf("freerdp_assistance_decrypt: %d\n", status); if (status < 0) return -1; printf("ConnectionString2: %s\n", file->ConnectionString2); - freerdp_client_assistance_file_free(file); + freerdp_assistance_file_free(file); return 0; } diff --git a/libfreerdp/core/settings.c b/libfreerdp/core/settings.c index 0843bbdd6..fc40a0633 100644 --- a/libfreerdp/core/settings.c +++ b/libfreerdp/core/settings.c @@ -465,6 +465,9 @@ rdpSettings* freerdp_settings_clone(rdpSettings* settings) _settings->ClientDir = _strdup(settings->ClientDir); /* 770 */ _settings->DynamicDSTTimeZoneKeyName = _strdup(settings->DynamicDSTTimeZoneKeyName); /* 897 */ _settings->RemoteAssistanceSessionId = _strdup(settings->RemoteAssistanceSessionId); /* 1025 */ + _settings->RemoteAssistancePassStub = _strdup(settings->RemoteAssistancePassStub); /* 1026 */ + _settings->RemoteAssistancePassword = _strdup(settings->RemoteAssistancePassword); /* 1027 */ + _settings->RemoteAssistanceRCTicket = _strdup(settings->RemoteAssistanceRCTicket); /* 1028 */ _settings->AuthenticationServiceClass = _strdup(settings->AuthenticationServiceClass); /* 1098 */ _settings->PreconnectionBlob = _strdup(settings->PreconnectionBlob); /* 1155 */ _settings->KerberosKdc = _strdup(settings->KerberosKdc); /* 1344 */