20#include <freerdp/config.h>
24#include <winpr/wtypes.h>
25#include <winpr/collections.h>
26#include <winpr/string.h>
28#include <winpr/crypto.h>
29#include <winpr/print.h>
30#include <winpr/windows.h>
32#include <winpr/file.h>
34#include <freerdp/log.h>
35#include <freerdp/client/file.h>
36#include <freerdp/client/cmdline.h>
38#include <freerdp/assistance.h>
40#include "../core/settings.h"
42#define TAG FREERDP_TAG("common")
44struct rdp_assistance_file
55 BOOL RCTicketEncrypted;
57 char* ConnectionString1;
58 char* ConnectionString2;
60 BYTE* EncryptedPassStub;
61 size_t EncryptedPassStubLength;
63 BYTE* EncryptedLHTicket;
64 size_t EncryptedLHTicketLength;
66 wArrayList* MachineAddresses;
67 wArrayList* MachinePorts;
68 wArrayList* MachineUris;
71 char* RASpecificParams;
72 char* RASpecificParams2;
78static const char* strrstr(
const char* haystack,
size_t len,
const char* needle)
86 char* p = strstr(haystack, needle);
89 if (p > haystack + len)
99static BOOL update_option(
char** opt,
const char* val,
size_t len)
105 if (!val && (len != 0))
107 else if (!val && (len == 0))
109 *opt = strndup(val, len);
113static BOOL update_name(rdpAssistanceFile* file,
const char* name)
119 WLog_ERR(TAG,
"ASSISTANCE file %s invalid name", name);
123 free(file->filename);
124 file->filename = _strdup(name);
125 return file->filename != NULL;
128static BOOL update_password(rdpAssistanceFile* file,
const char* password)
131 free(file->password);
132 file->password = NULL;
135 file->password = _strdup(password);
136 return file->password != NULL;
139static BOOL update_connectionstring2_nocopy(rdpAssistanceFile* file,
char* str)
142 free(file->ConnectionString2);
143 file->ConnectionString2 = NULL;
146 file->ConnectionString2 = str;
147 return file->ConnectionString2 != NULL;
150static BOOL update_connectionstring2(rdpAssistanceFile* file,
const char* str,
size_t len)
153 if (!str && (len != 0))
156 if (str && (len > 0))
158 strc = strndup(str, len);
162 return update_connectionstring2_nocopy(file, strc);
165static BOOL update_connectionstring2_wchar(rdpAssistanceFile* file,
const WCHAR* str,
size_t len)
169 if (!str && (len != 0))
172 if (str && (len > 0))
174 strc = ConvertWCharNToUtf8Alloc(str, len, NULL);
178 return update_connectionstring2_nocopy(file, strc);
217static BOOL freerdp_assistance_crypt_derive_key_sha1(
const BYTE* hash,
size_t hashLength, BYTE* key,
221 BYTE pad1[64] = { 0 };
222 BYTE pad2[64] = { 0 };
227 memset(pad1, 0x36,
sizeof(pad1));
228 memset(pad2, 0x5C,
sizeof(pad2));
230 for (
size_t i = 0; i < hashLength; i++)
236 BYTE* buffer = (BYTE*)calloc(hashLength, 2);
241 if (!winpr_Digest(WINPR_MD_SHA1, pad1, 64, buffer, hashLength))
244 if (!winpr_Digest(WINPR_MD_SHA1, pad2, 64, &buffer[hashLength], hashLength))
247 CopyMemory(key, buffer, keyLength);
254static BOOL append_address_to_list(wArrayList* MachineAddresses,
const char* str,
size_t len)
258 copy = strndup(str, len);
262 const BOOL rc = ArrayList_Append(MachineAddresses, copy);
269static BOOL append_address(rdpAssistanceFile* file,
const char* host,
const char* port)
274 unsigned long p = strtoul(port, NULL, 0);
276 if ((errno != 0) || (p == 0) || (p > UINT16_MAX))
278 WLog_ERR(TAG,
"Failed to parse ASSISTANCE file: ConnectionString2 invalid port value %s",
283 if (!append_address_to_list(file->MachineAddresses, host, host ? strlen(host) : 0))
285 return ArrayList_Append(file->MachinePorts, (
void*)(uintptr_t)p);
288static BOOL freerdp_assistance_parse_address_list(rdpAssistanceFile* file,
char* list)
292 WLog_DBG(TAG,
"freerdp_assistance_parse_address_list list=%s", list);
303 char* saveptr = NULL;
304 char* token = strtok_s(strp, s, &saveptr);
307 while (token != NULL)
309 char* port = strchr(token,
':');
315 if (!append_address(file, token, port))
318 token = strtok_s(NULL, s, &saveptr);
325static BOOL freerdp_assistance_parse_connection_string1(rdpAssistanceFile* file)
327 char* tokens[8] = { 0 };
339 char* str = _strdup(file->RCTicket);
345 const size_t length = strlen(str);
349 for (
size_t i = 0; i < length; i++)
361 tokens[count++] = str;
363 for (
size_t i = 0; i < length; i++)
368 tokens[count++] = &str[i + 1];
374 if (strcmp(tokens[0],
"65538") != 0)
377 if (strcmp(tokens[1],
"1") != 0)
380 if (strcmp(tokens[3],
"*") != 0)
383 if (strcmp(tokens[5],
"*") != 0)
386 if (strcmp(tokens[6],
"*") != 0)
389 file->RASessionId = _strdup(tokens[4]);
391 if (!file->RASessionId)
394 file->RASpecificParams = _strdup(tokens[7]);
396 if (!file->RASpecificParams)
399 if (!freerdp_assistance_parse_address_list(file, tokens[2]))
421static BOOL freerdp_assistance_parse_attr(
const char** opt,
size_t* plength,
const char* key,
425 WINPR_ASSERT(plength);
433 char bkey[128] = { 0 };
434 const int rc = _snprintf(bkey,
sizeof(bkey),
"%s=\"", key);
435 WINPR_ASSERT(rc > 0);
436 WINPR_ASSERT((
size_t)rc <
sizeof(bkey));
437 if ((rc <= 0) || ((
size_t)rc >=
sizeof(bkey)))
440 char* p = strstr(tag, bkey);
445 char* q = strchr(p,
'"');
449 WLog_ERR(TAG,
"Failed to parse ASSISTANCE file: ConnectionString2 invalid field '%s=%s'",
457 "Failed to parse ASSISTANCE file: ConnectionString2 invalid field "
462 const size_t length = WINPR_ASSERTING_INT_CAST(
size_t, q - p);
469static BOOL freerdp_assistance_parse_attr_str(
char** opt,
const char* key,
const char* tag)
471 const char* copt = NULL;
473 if (!freerdp_assistance_parse_attr(&copt, &size, key, tag))
475 return update_option(opt, copt, size);
478static BOOL freerdp_assistance_parse_attr_bool(BOOL* opt,
const char* key,
const char* tag)
480 const char* copt = NULL;
486 if (!freerdp_assistance_parse_attr(&copt, &size, key, tag))
491 *opt = (copt[0] ==
'1');
495static BOOL freerdp_assistance_parse_attr_uint32(UINT32* opt,
const char* key,
const char* tag)
497 const char* copt = NULL;
503 if (!freerdp_assistance_parse_attr(&copt, &size, key, tag))
506 char buffer[64] = { 0 };
507 if ((!copt && (size > 0)) || (size >=
sizeof(buffer)))
509 WLog_WARN(TAG,
"Invalid UINT32 string '%s' [%" PRIuz
"]", copt, size);
514 strncpy(buffer, copt, size);
517 unsigned long val = strtoul(buffer, NULL, 0);
519 if ((errno != 0) || (val > UINT32_MAX))
521 WLog_ERR(TAG,
"Failed to parse ASSISTANCE file: Invalid value %s", buffer);
530static char* freerdp_assistance_contains_element(
char* input,
size_t ilen,
const char* key,
531 size_t* plen,
char** pdata,
size_t* pdlen)
537 char bkey[128] = { 0 };
538 const int rc = _snprintf(bkey,
sizeof(bkey),
"<%s", key);
539 WINPR_ASSERT(rc > 0);
540 WINPR_ASSERT((
size_t)rc <
sizeof(bkey));
541 if ((rc < 0) || ((
size_t)rc >=
sizeof(bkey)))
544 char* tag = strstr(input, bkey);
545 if (!tag || (tag > input + ilen))
548 char* data = tag + strnlen(bkey,
sizeof(bkey));
560 "Failed to parse ASSISTANCE file: ConnectionString2 missing delimiter after "
566 char* start = strstr(tag,
">");
568 if (!start || (start > input + ilen))
570 WLog_ERR(TAG,
"Failed to parse ASSISTANCE file: ConnectionString2 missing field %s", bkey);
574 const char* end = start;
575 const char* dend = start - 1;
578 char ekey[128] = { 0 };
579 const int erc = _snprintf(ekey,
sizeof(ekey),
"</%s>", key);
580 WINPR_ASSERT(erc > 0);
581 WINPR_ASSERT((
size_t)erc <
sizeof(ekey));
582 if ((erc <= 0) || ((
size_t)erc >=
sizeof(ekey)))
584 const size_t offset = WINPR_ASSERTING_INT_CAST(
size_t, start - tag);
585 dend = end = strrstr(start, ilen - offset, ekey);
587 end += strnlen(ekey,
sizeof(ekey));
593 "Failed to parse ASSISTANCE file: ConnectionString2 missing end tag for field %s",
598 *plen = WINPR_ASSERTING_INT_CAST(
size_t, end - tag);
603 *pdlen = WINPR_ASSERTING_INT_CAST(
size_t, dend - data);
612static BOOL freerdp_assistance_consume_input_and_get_element(
char* input,
const char* key,
613 char** element,
size_t* elen)
617 WINPR_ASSERT(element);
623 char* tag = freerdp_assistance_contains_element(input, strlen(input), key, &len, &data, &dlen);
627 char* end = data + dlen;
635static BOOL freerdp_assistance_get_element(
char* input,
size_t ilen,
const char* key,
636 char** element,
size_t* elen)
640 WINPR_ASSERT(element);
646 char* tag = freerdp_assistance_contains_element(input, ilen, key, &len, &data, &dlen);
650 if (tag + len > input + ilen)
653 char* end = tag + len;
655 *elen = WINPR_ASSERTING_INT_CAST(
size_t, end - data + 1);
659static BOOL freerdp_assistance_parse_all_elements_of(rdpAssistanceFile* file,
char* data,
660 size_t len,
const char* key,
661 BOOL (*fkt)(rdpAssistanceFile* file,
662 char* data,
size_t len))
667 while (freerdp_assistance_get_element(data, len, key, &val, &vlen))
670 len = strnlen(data, len);
673 val[vlen - 1] =
'\0';
675 if (!fkt(file, val, vlen))
683static BOOL freerdp_assistance_parse_all_elements_of_l(rdpAssistanceFile* file,
char* data,
684 WINPR_ATTR_UNUSED
size_t len)
687 const char* n = NULL;
688 const char* u = NULL;
691 if (!freerdp_assistance_parse_attr_uint32(&p,
"P", data))
693 if (!freerdp_assistance_parse_attr(&n, &nlen,
"N", data))
695 if (!freerdp_assistance_parse_attr(&u, &ulen,
"U", data))
700 if (!append_address_to_list(file->MachineAddresses, n, nlen))
702 if (!ArrayList_Append(file->MachinePorts, (
void*)(uintptr_t)p))
707 if (!append_address_to_list(file->MachineAddresses, u, ulen))
709 if (!ArrayList_Append(file->MachinePorts, (
void*)(uintptr_t)p))
715static BOOL freerdp_assistance_parse_all_elements_of_t(rdpAssistanceFile* file,
char* data,
720 if (!freerdp_assistance_parse_attr_uint32(&
id,
"ID", data))
722 if (!freerdp_assistance_parse_attr_uint32(&sid,
"SID", data))
724 WLog_DBG(TAG,
"transport id=%" PRIu32
", sid=%" PRIu32,
id, sid);
725 return freerdp_assistance_parse_all_elements_of(file, data, len,
"L",
726 freerdp_assistance_parse_all_elements_of_l);
729static BOOL freerdp_assistance_parse_all_elements_of_c(rdpAssistanceFile* file,
char* data,
732 return freerdp_assistance_parse_all_elements_of(file, data, len,
"T",
733 freerdp_assistance_parse_all_elements_of_t);
736static BOOL freerdp_assistance_parse_find_elements_of_c(rdpAssistanceFile* file,
char* data,
739 return freerdp_assistance_parse_all_elements_of(file, data, len,
"C",
740 freerdp_assistance_parse_all_elements_of_c);
743static BOOL freerdp_assistance_parse_connection_string2(rdpAssistanceFile* file)
749 if (!file->ConnectionString2)
752 char* str = _strdup(file->ConnectionString2);
759 if (!freerdp_assistance_consume_input_and_get_element(str,
"E", &e, &elen))
762 if (!e || (elen == 0))
767 if (!freerdp_assistance_get_element(e, elen,
"A", &a, &alen))
770 if (!a || (alen == 0))
773 if (!freerdp_assistance_parse_find_elements_of_c(file, e, elen))
781 if (!freerdp_assistance_parse_attr_str(&file->RASpecificParams,
"KH", a))
784 if (!freerdp_assistance_parse_attr_str(&file->RASpecificParams2,
"KH2", a))
787 if (!freerdp_assistance_parse_attr_str(&file->RASessionId,
"ID", a))
797char* freerdp_assistance_construct_expert_blob(
const char* name,
const char* pass)
802 const size_t nameLength = strlen(name) + strlen(
"NAME=");
803 const size_t passLength = strlen(pass) + strlen(
"PASS=");
804 const size_t size = nameLength + passLength + 64;
805 char* ExpertBlob = (
char*)calloc(1, size);
810 (void)sprintf_s(ExpertBlob, size,
"%" PRIuz
";NAME=%s%" PRIuz
";PASS=%s", nameLength, name,
815char* freerdp_assistance_generate_pass_stub(WINPR_ATTR_UNUSED DWORD flags)
817 UINT32 nums[14] = { 0 };
818 const char set1[64] = {
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
819 'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z',
820 'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'l',
'm',
821 'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
'w',
'x',
'y',
'z',
822 '0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'*',
'_' };
823 const char set2[12] = {
'!',
'@',
'#',
'$',
'&',
'^',
'*',
'(',
')',
'-',
'+',
'=' };
824 const char set3[10] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9' };
825 const char set4[26] = {
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
826 'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z' };
827 const char set5[26] = {
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'l',
'm',
828 'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
'w',
'x',
'y',
'z' };
829 char* passStub = calloc(15,
sizeof(
char));
845 winpr_RAND(nums,
sizeof(nums));
846 passStub[0] = set1[nums[0] %
sizeof(set1)];
847 passStub[1] = set2[nums[1] %
sizeof(set2)];
848 passStub[2] = set3[nums[2] %
sizeof(set3)];
849 passStub[3] = set4[nums[3] %
sizeof(set4)];
850 passStub[4] = set5[nums[4] %
sizeof(set5)];
852 for (
size_t x = 5; x < ARRAYSIZE(nums); x++)
853 passStub[x] = set1[nums[x] %
sizeof(set1)];
857BYTE* freerdp_assistance_encrypt_pass_stub(
const char* password,
const char* passStub,
858 size_t* pEncryptedSize)
861 size_t cbPasswordW = 0;
862 size_t cbPassStubW = 0;
863 BYTE PasswordHash[WINPR_MD5_DIGEST_LENGTH] = { 0 };
864 WINPR_RC4_CTX* rc4Ctx = NULL;
868 WCHAR* PasswordW = ConvertUtf8ToWCharAlloc(password, &cbPasswordW);
869 WCHAR* PassStubW = ConvertUtf8ToWCharAlloc(passStub, &cbPassStubW);
871 cbPasswordW = (cbPasswordW) *
sizeof(WCHAR);
872 cbPassStubW = (cbPassStubW) *
sizeof(WCHAR);
873 const size_t EncryptedSize = cbPassStubW + 4;
875 if (!PasswordW || !PassStubW)
878 if (!winpr_Digest(WINPR_MD_MD5, (BYTE*)PasswordW, cbPasswordW, (BYTE*)PasswordHash,
879 sizeof(PasswordHash)))
882 pbIn = (BYTE*)calloc(1, EncryptedSize);
883 pbOut = (BYTE*)calloc(1, EncryptedSize);
888 WINPR_ASSERT(cbPasswordW <= UINT32_MAX);
889 winpr_Data_Write_UINT32(pbIn, (UINT32)cbPassStubW);
890 CopyMemory(&pbIn[4], PassStubW, cbPassStubW);
891 rc4Ctx = winpr_RC4_New(PasswordHash,
sizeof(PasswordHash));
895 WLog_ERR(TAG,
"winpr_Cipher_New failure");
899 rc = winpr_RC4_Update(rc4Ctx, EncryptedSize, pbIn, pbOut);
903 WLog_ERR(TAG,
"winpr_Cipher_Update failure");
908 winpr_RC4_Free(rc4Ctx);
915 *pEncryptedSize = EncryptedSize;
919static BOOL freerdp_assistance_decrypt2(rdpAssistanceFile* file)
923 size_t cbPasswordW = 0;
925 WINPR_CIPHER_CTX* aesDec = NULL;
926 WCHAR* PasswordW = NULL;
932 BYTE DerivedKey[WINPR_AES_BLOCK_SIZE] = { 0 };
933 BYTE InitializationVector[WINPR_AES_BLOCK_SIZE] = { 0 };
934 BYTE PasswordHash[WINPR_SHA1_DIGEST_LENGTH] = { 0 };
941 PasswordW = ConvertUtf8ToWCharAlloc(file->password, &cbPasswordW);
944 WLog_ERR(TAG,
"Failed to parse ASSISTANCE file: Conversion from UCS2 to UTF8 failed");
948 cbPasswordW = (cbPasswordW) *
sizeof(WCHAR);
950 if (!winpr_Digest(WINPR_MD_SHA1, (BYTE*)PasswordW, cbPasswordW, PasswordHash,
951 sizeof(PasswordHash)))
954 if (!freerdp_assistance_crypt_derive_key_sha1(PasswordHash,
sizeof(PasswordHash), DerivedKey,
959 winpr_Cipher_NewEx(WINPR_CIPHER_AES_128_CBC, WINPR_DECRYPT, DerivedKey,
sizeof(DerivedKey),
960 InitializationVector,
sizeof(InitializationVector));
966 cbIn = file->EncryptedLHTicketLength;
967 pbIn = file->EncryptedLHTicket;
968 pbOut = (BYTE*)calloc(1, cbIn + WINPR_AES_BLOCK_SIZE + 2);
973 if (!winpr_Cipher_Update(aesDec, pbIn, cbIn, pbOut, &cbOut))
976 if (!winpr_Cipher_Final(aesDec, pbOut + cbOut, &cbFinal))
978 WLog_ERR(TAG,
"winpr_Cipher_Final failure");
992 cchOutW = cbOut /
sizeof(WCHAR);
994 if (!update_connectionstring2_wchar(file, cnv.wc, cchOutW))
996 WLog_ERR(TAG,
"Failed to parse ASSISTANCE file: Conversion from UCS2 to UTF8 failed");
1000 if (!freerdp_assistance_parse_connection_string2(file))
1005 winpr_Cipher_Free(aesDec);
1008 WLog_DBG(TAG,
"freerdp_assistance_parse_connection_string2: %d", status);
1012BYTE* freerdp_assistance_hex_string_to_bin(
const void* raw,
size_t* size)
1014 BYTE* buffer = NULL;
1018 const size_t length = strlen(raw);
1019 buffer = calloc(length,
sizeof(BYTE));
1022 const size_t rc = winpr_HexStringToBinBuffer(raw, length, buffer, length);
1032char* freerdp_assistance_bin_to_hex_string(
const void* raw,
size_t size)
1034 return winpr_BinToHexString(raw, size, FALSE);
1037static int freerdp_assistance_parse_uploadinfo(rdpAssistanceFile* file,
char* uploadinfo,
1038 size_t uploadinfosize)
1040 const char escalated[9] = {
'E',
's',
'c',
'a',
'l',
'a',
't',
'e',
'd' };
1041 const size_t esclen =
sizeof(escalated);
1042 const char* typestr = NULL;
1045 if (!uploadinfo || (uploadinfosize == 0))
1048 if (strnlen(uploadinfo, uploadinfosize) == uploadinfosize)
1050 WLog_WARN(TAG,
"UPLOADINFOR string is not '\0' terminated");
1054 if (!freerdp_assistance_parse_attr(&typestr, &typelen,
"TYPE", uploadinfo))
1057 if ((typelen != esclen) || (strncmp(typestr, escalated, esclen) != 0))
1060 "Failed to parse ASSISTANCE file: Missing or invalid UPLOADINFO TYPE '%s' [%" PRIuz
1066 char* uploaddata = NULL;
1067 size_t uploaddatasize = 0;
1068 if (!freerdp_assistance_consume_input_and_get_element(uploadinfo,
"UPLOADDATA", &uploaddata,
1073 if (!freerdp_assistance_parse_attr_str(&file->Username,
"USERNAME", uploaddata))
1077 if (!freerdp_assistance_parse_attr_str(&file->LHTicket,
"LHTICKET", uploaddata))
1081 if (!freerdp_assistance_parse_attr_str(&file->RCTicket,
"RCTICKET", uploaddata))
1085 if (!freerdp_assistance_parse_attr_bool(&file->RCTicketEncrypted,
"RCTICKETENCRYPTED",
1090 if (!freerdp_assistance_parse_attr_str(&file->PassStub,
"PassStub", uploaddata))
1095 const char* amp =
"&";
1096 char* passtub = strstr(file->PassStub, amp);
1099 const char* end = passtub + 5;
1100 const size_t len = strlen(end);
1101 memmove(&passtub[1], end, len + 1);
1102 passtub = strstr(passtub, amp);
1107 if (!freerdp_assistance_parse_attr_uint32(&file->DtStart,
"DtStart", uploaddata))
1111 if (!freerdp_assistance_parse_attr_uint32(&file->DtLength,
"DtLength", uploaddata))
1115 if (!freerdp_assistance_parse_attr_bool(&file->LowSpeed,
"L", uploaddata))
1118 file->Type = (file->LHTicket) ? 2 : 1;
1125 file->EncryptedLHTicket = freerdp_assistance_hex_string_to_bin(
1126 file->LHTicket, &file->EncryptedLHTicketLength);
1128 if (!freerdp_assistance_decrypt2(file))
1135 if (!freerdp_assistance_parse_connection_string1(file))
1146 WLog_ERR(TAG,
"freerdp_assistance_parse_connection_string1 failure: %d", status);
1150 file->EncryptedPassStub = freerdp_assistance_encrypt_pass_stub(file->password, file->PassStub,
1151 &file->EncryptedPassStubLength);
1153 if (!file->EncryptedPassStub)
1159static int freerdp_assistance_parse_file_buffer_int(rdpAssistanceFile* file,
char* buffer,
1160 size_t size,
const char* password)
1163 WINPR_ASSERT(buffer);
1164 WINPR_ASSERT(size > 0);
1166 if (!update_password(file, password))
1169 char* uploadinfo = NULL;
1170 size_t uploadinfosize = 0;
1171 if (freerdp_assistance_consume_input_and_get_element(buffer,
"UPLOADINFO", &uploadinfo,
1173 return freerdp_assistance_parse_uploadinfo(file, uploadinfo, uploadinfosize);
1176 const char* estr = freerdp_assistance_contains_element(buffer, size,
"E", &elen, NULL, NULL);
1177 if (!estr || (elen == 0))
1179 WLog_ERR(TAG,
"Failed to parse ASSISTANCE file: Neither UPLOADINFO nor <E> found");
1182 if (!update_connectionstring2(file, estr, elen))
1185 if (!freerdp_assistance_parse_connection_string2(file))
1191int freerdp_assistance_parse_file_buffer(rdpAssistanceFile* file,
const char* cbuffer,
size_t size,
1192 const char* password)
1197 WLog_WARN(TAG,
"empty password supplied");
1200 if (!cbuffer || (size == 0))
1202 WLog_WARN(TAG,
"no data supplied [%p, %" PRIuz
"]", cbuffer, size);
1206 char* abuffer = strndup(cbuffer, size);
1207 const size_t len = strnlen(cbuffer, size);
1209 WLog_WARN(TAG,
"Input data not '\0' terminated");
1214 const int rc = freerdp_assistance_parse_file_buffer_int(file, abuffer, len + 1, password);
1219int freerdp_assistance_parse_file(rdpAssistanceFile* file,
const char* name,
const char* password)
1222 BYTE* buffer = NULL;
1224 size_t readSize = 0;
1231 if (!update_name(file, name))
1234 fp = winpr_fopen(name,
"r");
1238 WLog_ERR(TAG,
"Failed to open ASSISTANCE file %s ", name);
1242 (void)_fseeki64(fp, 0, SEEK_END);
1243 fileSize.i64 = _ftelli64(fp);
1244 (void)_fseeki64(fp, 0, SEEK_SET);
1246 if (fileSize.i64 < 1)
1248 WLog_ERR(TAG,
"Failed to read ASSISTANCE file %s ", name);
1253 buffer = (BYTE*)malloc(fileSize.s + 2);
1261 readSize = fread(buffer, fileSize.s, 1, fp);
1266 readSize = fileSize.s;
1273 WLog_ERR(TAG,
"Failed to read ASSISTANCE file %s ", name);
1279 buffer[fileSize.s] =
'\0';
1280 buffer[fileSize.s + 1] =
'\0';
1281 status = freerdp_assistance_parse_file_buffer(file, (
char*)buffer, fileSize.s, password);
1286BOOL freerdp_assistance_populate_settings_from_assistance_file(rdpAssistanceFile* file,
1287 rdpSettings* settings)
1292 if (!file->RASessionId || !file->MachineAddresses)
1308 file->ConnectionString2))
1319 if (ArrayList_Count(file->MachineAddresses) < 1)
1322 const char* addr = ArrayList_GetItem(file->MachineAddresses, 0);
1341 const size_t ports = ArrayList_Count(file->MachinePorts);
1342 const size_t addresses = ArrayList_Count(file->MachineAddresses);
1345 if (ports != addresses)
1353 cnv.data = ArrayList_GetItem(file->MachinePorts, 0);
1354 WINPR_ASSERT(cnv.port <= UINT32_MAX);
1358 if (!freerdp_target_net_adresses_reset(settings, ports))
1361 for (
size_t x = 0; x < ports; x++)
1363 cnv.data = ArrayList_GetItem(file->MachinePorts, x);
1364 WINPR_ASSERT(cnv.port <= UINT32_MAX);
1365 const UINT32 port = (UINT32)cnv.port;
1366 if (!freerdp_settings_set_pointer_array(settings, FreeRDP_TargetNetPorts, x, &port))
1369 for (
size_t i = 0; i < addresses; i++)
1371 const char* maddr = ArrayList_GetItem(file->MachineAddresses, i);
1372 if (!freerdp_settings_set_pointer_array(settings, FreeRDP_TargetNetAddresses, i, maddr))
1379static BOOL setup_string(wArrayList* list)
1383 wObject* obj = ArrayList_Object(list);
1386 obj->fnObjectFree = free;
1391rdpAssistanceFile* freerdp_assistance_file_new(
void)
1393 winpr_InitializeSSL(WINPR_SSL_INIT_DEFAULT);
1394 rdpAssistanceFile* file = calloc(1,
sizeof(rdpAssistanceFile));
1398 file->MachineAddresses = ArrayList_New(FALSE);
1399 file->MachinePorts = ArrayList_New(FALSE);
1400 file->MachineUris = ArrayList_New(FALSE);
1402 if (!file->MachineAddresses || !file->MachinePorts || !file->MachineUris)
1405 if (!setup_string(file->MachineAddresses) || !setup_string(file->MachineUris))
1411 WINPR_PRAGMA_DIAG_PUSH
1412 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
1413 freerdp_assistance_file_free(file);
1414 WINPR_PRAGMA_DIAG_POP
1418void freerdp_assistance_file_free(rdpAssistanceFile* file)
1423 update_password(file, NULL);
1424 update_connectionstring2(file, NULL, 0);
1425 free(file->filename);
1426 free(file->Username);
1427 free(file->LHTicket);
1428 free(file->RCTicket);
1429 free(file->PassStub);
1430 free(file->ConnectionString1);
1431 free(file->EncryptedLHTicket);
1432 free(file->RASessionId);
1433 free(file->RASpecificParams);
1434 free(file->RASpecificParams2);
1435 free(file->EncryptedPassStub);
1437 ArrayList_Free(file->MachineAddresses);
1438 ArrayList_Free(file->MachinePorts);
1439 ArrayList_Free(file->MachineUris);
1443void freerdp_assistance_print_file(rdpAssistanceFile* file, wLog* log, DWORD level)
1447 WLog_Print(log, level,
"Username: %s", file->Username);
1448 WLog_Print(log, level,
"LHTicket: %s", file->LHTicket);
1449 WLog_Print(log, level,
"RCTicket: %s", file->RCTicket);
1450 WLog_Print(log, level,
"RCTicketEncrypted: %" PRId32, file->RCTicketEncrypted);
1451 WLog_Print(log, level,
"PassStub: %s", file->PassStub);
1452 WLog_Print(log, level,
"DtStart: %" PRIu32, file->DtStart);
1453 WLog_Print(log, level,
"DtLength: %" PRIu32, file->DtLength);
1454 WLog_Print(log, level,
"LowSpeed: %" PRId32, file->LowSpeed);
1455 WLog_Print(log, level,
"RASessionId: %s", file->RASessionId);
1456 WLog_Print(log, level,
"RASpecificParams: %s", file->RASpecificParams);
1457 WLog_Print(log, level,
"RASpecificParams2: %s", file->RASpecificParams2);
1459 for (
size_t x = 0; x < ArrayList_Count(file->MachineAddresses); x++)
1462 const char* uri = NULL;
1463 const char* addr = ArrayList_GetItem(file->MachineAddresses, x);
1464 if (x < ArrayList_Count(file->MachinePorts))
1471 cnv.data = ArrayList_GetItem(file->MachinePorts, x);
1472 WINPR_ASSERT(cnv.port <= UINT32_MAX);
1473 port = (UINT32)cnv.port;
1475 if (x < ArrayList_Count(file->MachineUris))
1476 uri = ArrayList_GetItem(file->MachineUris, x);
1478 WLog_Print(log, level,
"MachineAddress [%" PRIuz
": %s", x, addr);
1479 WLog_Print(log, level,
"MachinePort [%" PRIuz
": %" PRIu32, x, port);
1480 WLog_Print(log, level,
"MachineURI [%" PRIuz
": %s", x, uri);
1484BOOL freerdp_assistance_get_encrypted_pass_stub(rdpAssistanceFile* file,
const char** pwd,
1487 if (!file || !pwd || !size)
1490 *pwd = (
const char*)file->EncryptedPassStub;
1491 *size = file->EncryptedPassStubLength;
1495int freerdp_assistance_set_connection_string2(rdpAssistanceFile* file,
const char*
string,
1496 const char* password)
1498 if (!file || !
string || !password)
1501 char* str = _strdup(
string);
1505 if (!update_connectionstring2_nocopy(file, str))
1507 if (!update_password(file, password))
1509 return freerdp_assistance_parse_connection_string2(file);
FREERDP_API BOOL freerdp_settings_set_string(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const char *param)
Sets a string settings value. The param is copied.
FREERDP_API BOOL freerdp_settings_set_uint32(rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id, UINT32 param)
Sets a UINT32 settings value.
FREERDP_API BOOL freerdp_settings_set_bool(rdpSettings *settings, FreeRDP_Settings_Keys_Bool id, BOOL param)
Sets a BOOL settings value.
This struct contains function pointer to initialize/free objects.