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)
83 char* result =
nullptr;
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);
110 return *opt !=
nullptr;
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 !=
nullptr;
128static BOOL update_password(rdpAssistanceFile* file,
const char* password)
131 free(file->password);
132 file->password =
nullptr;
135 file->password = _strdup(password);
136 return file->password !=
nullptr;
139static BOOL update_connectionstring2_nocopy(rdpAssistanceFile* file,
char* str)
142 free(file->ConnectionString2);
143 file->ConnectionString2 =
nullptr;
146 file->ConnectionString2 = str;
147 return file->ConnectionString2 !=
nullptr;
150static BOOL update_connectionstring2(rdpAssistanceFile* file,
const char* str,
size_t len)
152 char* strc =
nullptr;
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)
167 char* strc =
nullptr;
169 if (!str && (len != 0))
172 if (str && (len > 0))
174 strc = ConvertWCharNToUtf8Alloc(str, len,
nullptr);
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] = WINPR_C_ARRAY_INIT;
222 BYTE pad2[64] = WINPR_C_ARRAY_INIT;
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)
256 char* copy =
nullptr;
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,
nullptr, 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 =
nullptr;
304 char* token = strtok_s(strp, s, &saveptr);
307 while (token !=
nullptr)
309 char* port = strchr(token,
':');
315 if (!append_address(file, token, port))
318 token = strtok_s(
nullptr, s, &saveptr);
325static BOOL freerdp_assistance_parse_connection_string1(rdpAssistanceFile* file)
327 char* tokens[8] = WINPR_C_ARRAY_INIT;
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] = WINPR_C_ARRAY_INIT;
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 =
nullptr;
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 =
nullptr;
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 =
nullptr;
503 if (!freerdp_assistance_parse_attr(&copt, &size, key, tag))
506 char buffer[64] = WINPR_C_ARRAY_INIT;
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,
nullptr, 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] = WINPR_C_ARRAY_INIT;
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 = winpr_strnstr(input, bkey, ilen);
548 const intptr_t tdiff = (tag - input);
549 WINPR_ASSERT(tdiff >= 0);
550 const size_t utdiff = WINPR_ASSERTING_INT_CAST(
size_t, tdiff);
551 WINPR_ASSERT(utdiff <= ilen);
552 const size_t tlen = ilen - utdiff;
553 const size_t texpect = strnlen(bkey,
sizeof(bkey));
557 char* data = tag + texpect;
569 "Failed to parse ASSISTANCE file: ConnectionString2 missing delimiter after "
575 const char* start = winpr_strnstr(tag,
">", tlen);
577 if (!start || (start > input + ilen))
579 WLog_ERR(TAG,
"Failed to parse ASSISTANCE file: ConnectionString2 missing field %s", bkey);
583 const char* end = start;
584 const char* dend = start - 1;
587 char ekey[128] = WINPR_C_ARRAY_INIT;
588 const int erc = _snprintf(ekey,
sizeof(ekey),
"</%s>", key);
589 WINPR_ASSERT(erc > 0);
590 WINPR_ASSERT((
size_t)erc <
sizeof(ekey));
591 if ((erc <= 0) || ((
size_t)erc >=
sizeof(ekey)))
593 const size_t offset = WINPR_ASSERTING_INT_CAST(
size_t, start - tag);
594 dend = end = strrstr(start, ilen - offset, ekey);
596 end += strnlen(ekey,
sizeof(ekey));
602 "Failed to parse ASSISTANCE file: ConnectionString2 missing end tag for field %s",
607 *plen = WINPR_ASSERTING_INT_CAST(
size_t, end - tag);
612 *pdlen = WINPR_ASSERTING_INT_CAST(
size_t, dend - data);
621static BOOL freerdp_assistance_consume_input_and_get_element(
char* input,
size_t ilen,
622 const char* key,
char** element,
627 WINPR_ASSERT(element);
632 char* data =
nullptr;
633 char* tag = freerdp_assistance_contains_element(input, ilen, key, &len, &data, &dlen);
637 char* end = data + dlen;
645static BOOL freerdp_assistance_get_element(
char* input,
size_t ilen,
const char* key,
646 char** element,
size_t* elen)
650 WINPR_ASSERT(element);
655 char* data =
nullptr;
656 char* tag = freerdp_assistance_contains_element(input, ilen, key, &len, &data, &dlen);
660 if (tag + len > input + ilen)
663 char* end = tag + len;
665 *elen = WINPR_ASSERTING_INT_CAST(
size_t, end - data + 1);
669static BOOL freerdp_assistance_parse_all_elements_of(rdpAssistanceFile* file,
char* data,
670 size_t len,
const char* key,
671 BOOL (*fkt)(rdpAssistanceFile* file,
672 char* data,
size_t len))
677 while (freerdp_assistance_get_element(data, len, key, &val, &vlen))
680 len = strnlen(data, len);
683 val[vlen - 1] =
'\0';
685 if (!fkt(file, val, vlen))
693static BOOL freerdp_assistance_parse_all_elements_of_l(rdpAssistanceFile* file,
char* data,
694 WINPR_ATTR_UNUSED
size_t len)
697 const char* n =
nullptr;
698 const char* u =
nullptr;
701 if (!freerdp_assistance_parse_attr_uint32(&p,
"P", data))
703 if (!freerdp_assistance_parse_attr(&n, &nlen,
"N", data))
705 if (!freerdp_assistance_parse_attr(&u, &ulen,
"U", data))
710 if (!append_address_to_list(file->MachineAddresses, n, nlen))
712 if (!ArrayList_Append(file->MachinePorts, (
void*)(uintptr_t)p))
717 if (!append_address_to_list(file->MachineAddresses, u, ulen))
719 if (!ArrayList_Append(file->MachinePorts, (
void*)(uintptr_t)p))
725static BOOL freerdp_assistance_parse_all_elements_of_t(rdpAssistanceFile* file,
char* data,
730 if (!freerdp_assistance_parse_attr_uint32(&
id,
"ID", data))
732 if (!freerdp_assistance_parse_attr_uint32(&sid,
"SID", data))
734 WLog_DBG(TAG,
"transport id=%" PRIu32
", sid=%" PRIu32,
id, sid);
735 return freerdp_assistance_parse_all_elements_of(file, data, len,
"L",
736 freerdp_assistance_parse_all_elements_of_l);
739static BOOL freerdp_assistance_parse_all_elements_of_c(rdpAssistanceFile* file,
char* data,
742 return freerdp_assistance_parse_all_elements_of(file, data, len,
"T",
743 freerdp_assistance_parse_all_elements_of_t);
746static BOOL freerdp_assistance_parse_find_elements_of_c(rdpAssistanceFile* file,
char* data,
749 return freerdp_assistance_parse_all_elements_of(file, data, len,
"C",
750 freerdp_assistance_parse_all_elements_of_c);
753static BOOL freerdp_assistance_parse_connection_string2(rdpAssistanceFile* file)
759 if (!file->ConnectionString2)
762 char* str = _strdup(file->ConnectionString2);
765 const size_t slen = strlen(str);
770 if (!freerdp_assistance_consume_input_and_get_element(str, slen,
"E", &e, &elen))
773 if (!e || (elen == 0))
778 if (!freerdp_assistance_get_element(e, elen,
"A", &a, &alen))
781 if (!a || (alen == 0))
784 if (!freerdp_assistance_parse_find_elements_of_c(file, e, elen))
792 if (!freerdp_assistance_parse_attr_str(&file->RASpecificParams,
"KH", a))
795 if (!freerdp_assistance_parse_attr_str(&file->RASpecificParams2,
"KH2", a))
798 if (!freerdp_assistance_parse_attr_str(&file->RASessionId,
"ID", a))
808char* freerdp_assistance_construct_expert_blob(
const char* name,
const char* pass)
813 const size_t nameLength = strlen(name) + strlen(
"NAME=");
814 const size_t passLength = strlen(pass) + strlen(
"PASS=");
815 const size_t size = nameLength + passLength + 64;
816 char* ExpertBlob = (
char*)calloc(1, size);
821 (void)sprintf_s(ExpertBlob, size,
"%" PRIuz
";NAME=%s%" PRIuz
";PASS=%s", nameLength, name,
826char* freerdp_assistance_generate_pass_stub(WINPR_ATTR_UNUSED DWORD flags)
828 UINT32 nums[14] = WINPR_C_ARRAY_INIT;
829 const char set1[64] = {
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
830 'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z',
831 'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'l',
'm',
832 'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
'w',
'x',
'y',
'z',
833 '0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'*',
'_' };
834 const char set2[12] = {
'!',
'@',
'#',
'$',
'&',
'^',
'*',
'(',
')',
'-',
'+',
'=' };
835 const char set3[10] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9' };
836 const char set4[26] = {
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
837 'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z' };
838 const char set5[26] = {
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'l',
'm',
839 'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
'w',
'x',
'y',
'z' };
840 char* passStub = calloc(15,
sizeof(
char));
856 if (winpr_RAND(nums,
sizeof(nums)) < 0)
862 passStub[0] = set1[nums[0] %
sizeof(set1)];
863 passStub[1] = set2[nums[1] %
sizeof(set2)];
864 passStub[2] = set3[nums[2] %
sizeof(set3)];
865 passStub[3] = set4[nums[3] %
sizeof(set4)];
866 passStub[4] = set5[nums[4] %
sizeof(set5)];
868 for (
size_t x = 5; x < ARRAYSIZE(nums); x++)
869 passStub[x] = set1[nums[x] %
sizeof(set1)];
873BYTE* freerdp_assistance_encrypt_pass_stub(
const char* password,
const char* passStub,
874 size_t* pEncryptedSize)
877 size_t cbPasswordW = 0;
878 size_t cbPassStubW = 0;
879 BYTE PasswordHash[WINPR_MD5_DIGEST_LENGTH] = WINPR_C_ARRAY_INIT;
880 WINPR_RC4_CTX* rc4Ctx =
nullptr;
881 BYTE* pbIn =
nullptr;
882 BYTE* pbOut =
nullptr;
884 WCHAR* PasswordW = ConvertUtf8ToWCharAlloc(password, &cbPasswordW);
885 WCHAR* PassStubW = ConvertUtf8ToWCharAlloc(passStub, &cbPassStubW);
887 cbPasswordW = cbPasswordW *
sizeof(WCHAR);
888 cbPassStubW = cbPassStubW *
sizeof(WCHAR);
889 const size_t EncryptedSize = cbPassStubW + 4;
891 if (!PasswordW || !PassStubW)
894 if (!winpr_Digest(WINPR_MD_MD5, (BYTE*)PasswordW, cbPasswordW, (BYTE*)PasswordHash,
895 sizeof(PasswordHash)))
898 pbIn = (BYTE*)calloc(1, EncryptedSize);
899 pbOut = (BYTE*)calloc(1, EncryptedSize);
904 WINPR_ASSERT(cbPasswordW <= UINT32_MAX);
905 winpr_Data_Write_UINT32(pbIn, (UINT32)cbPassStubW);
906 CopyMemory(&pbIn[4], PassStubW, cbPassStubW);
907 rc4Ctx = winpr_RC4_New(PasswordHash,
sizeof(PasswordHash));
911 WLog_ERR(TAG,
"winpr_Cipher_New failure");
915 rc = winpr_RC4_Update(rc4Ctx, EncryptedSize, pbIn, pbOut);
919 WLog_ERR(TAG,
"winpr_Cipher_Update failure");
924 winpr_RC4_Free(rc4Ctx);
931 *pEncryptedSize = EncryptedSize;
935static BOOL freerdp_assistance_decrypt2(rdpAssistanceFile* file)
939 size_t cbPasswordW = 0;
941 WINPR_CIPHER_CTX* aesDec =
nullptr;
942 WCHAR* PasswordW =
nullptr;
943 BYTE* pbIn =
nullptr;
944 BYTE* pbOut =
nullptr;
948 BYTE DerivedKey[WINPR_AES_BLOCK_SIZE] = WINPR_C_ARRAY_INIT;
949 BYTE InitializationVector[WINPR_AES_BLOCK_SIZE] = WINPR_C_ARRAY_INIT;
950 BYTE PasswordHash[WINPR_SHA1_DIGEST_LENGTH] = WINPR_C_ARRAY_INIT;
957 PasswordW = ConvertUtf8ToWCharAlloc(file->password, &cbPasswordW);
960 WLog_ERR(TAG,
"Failed to parse ASSISTANCE file: Conversion from UCS2 to UTF8 failed");
964 cbPasswordW = cbPasswordW *
sizeof(WCHAR);
966 if (!winpr_Digest(WINPR_MD_SHA1, (BYTE*)PasswordW, cbPasswordW, PasswordHash,
967 sizeof(PasswordHash)))
970 if (!freerdp_assistance_crypt_derive_key_sha1(PasswordHash,
sizeof(PasswordHash), DerivedKey,
975 winpr_Cipher_NewEx(WINPR_CIPHER_AES_128_CBC, WINPR_DECRYPT, DerivedKey,
sizeof(DerivedKey),
976 InitializationVector,
sizeof(InitializationVector));
982 cbIn = file->EncryptedLHTicketLength;
983 pbIn = file->EncryptedLHTicket;
984 pbOut = (BYTE*)calloc(1, cbIn + WINPR_AES_BLOCK_SIZE + 2);
989 if (!winpr_Cipher_Update(aesDec, pbIn, cbIn, pbOut, &cbOut))
992 if (!winpr_Cipher_Final(aesDec, pbOut + cbOut, &cbFinal))
994 WLog_ERR(TAG,
"winpr_Cipher_Final failure");
1008 cchOutW = cbOut /
sizeof(WCHAR);
1010 if (!update_connectionstring2_wchar(file, cnv.wc, cchOutW))
1012 WLog_ERR(TAG,
"Failed to parse ASSISTANCE file: Conversion from UCS2 to UTF8 failed");
1016 if (!freerdp_assistance_parse_connection_string2(file))
1021 winpr_Cipher_Free(aesDec);
1024 WLog_DBG(TAG,
"freerdp_assistance_parse_connection_string2: %d", status);
1028BYTE* freerdp_assistance_hex_string_to_bin(
const void* str,
size_t* size)
1030 BYTE* buffer =
nullptr;
1034 const size_t length = strlen(str);
1035 buffer = calloc(length,
sizeof(BYTE));
1038 const size_t rc = winpr_HexStringToBinBuffer(str, length, buffer, length);
1048char* freerdp_assistance_bin_to_hex_string(
const void* data,
size_t size)
1050 return winpr_BinToHexString(data, size, FALSE);
1053static int freerdp_assistance_parse_uploadinfo(rdpAssistanceFile* file,
char* uploadinfo,
1054 size_t uploadinfosize)
1056 const char escalated[9] = {
'E',
's',
'c',
'a',
'l',
'a',
't',
'e',
'd' };
1057 const size_t esclen =
sizeof(escalated);
1058 const char* typestr =
nullptr;
1061 if (!uploadinfo || (uploadinfosize == 0))
1064 const size_t ulen = strnlen(uploadinfo, uploadinfosize);
1065 if (ulen == uploadinfosize)
1067 WLog_WARN(TAG,
"UPLOADINFOR string is not '\\0' terminated");
1071 if (!freerdp_assistance_parse_attr(&typestr, &typelen,
"TYPE", uploadinfo))
1074 if ((typelen != esclen) || (strncmp(typestr, escalated, esclen) != 0))
1077 "Failed to parse ASSISTANCE file: Missing or invalid UPLOADINFO TYPE '%s' [%" PRIuz
1083 char* uploaddata =
nullptr;
1084 size_t uploaddatasize = 0;
1085 if (!freerdp_assistance_consume_input_and_get_element(uploadinfo, ulen,
"UPLOADDATA",
1086 &uploaddata, &uploaddatasize))
1090 if (!freerdp_assistance_parse_attr_str(&file->Username,
"USERNAME", uploaddata))
1094 if (!freerdp_assistance_parse_attr_str(&file->LHTicket,
"LHTICKET", uploaddata))
1098 if (!freerdp_assistance_parse_attr_str(&file->RCTicket,
"RCTICKET", uploaddata))
1102 if (!freerdp_assistance_parse_attr_bool(&file->RCTicketEncrypted,
"RCTICKETENCRYPTED",
1107 if (!freerdp_assistance_parse_attr_str(&file->PassStub,
"PassStub", uploaddata))
1112 const char* amp =
"&";
1113 char* passtub = strstr(file->PassStub, amp);
1116 const char* end = passtub + 5;
1117 const size_t len = strlen(end);
1118 memmove(&passtub[1], end, len + 1);
1119 passtub = strstr(passtub, amp);
1124 if (!freerdp_assistance_parse_attr_uint32(&file->DtStart,
"DtStart", uploaddata))
1128 if (!freerdp_assistance_parse_attr_uint32(&file->DtLength,
"DtLength", uploaddata))
1132 if (!freerdp_assistance_parse_attr_bool(&file->LowSpeed,
"L", uploaddata))
1135 file->Type = (file->LHTicket) ? 2 : 1;
1142 file->EncryptedLHTicket = freerdp_assistance_hex_string_to_bin(
1143 file->LHTicket, &file->EncryptedLHTicketLength);
1145 if (!freerdp_assistance_decrypt2(file))
1152 if (!freerdp_assistance_parse_connection_string1(file))
1163 WLog_ERR(TAG,
"freerdp_assistance_parse_connection_string1 failure: %d", status);
1167 file->EncryptedPassStub = freerdp_assistance_encrypt_pass_stub(file->password, file->PassStub,
1168 &file->EncryptedPassStubLength);
1170 if (!file->EncryptedPassStub)
1176static int freerdp_assistance_parse_file_buffer_int(rdpAssistanceFile* file,
char* buffer,
1177 size_t size,
const char* password)
1180 WINPR_ASSERT(buffer);
1181 WINPR_ASSERT(size > 0);
1183 if (!update_password(file, password))
1186 char* uploadinfo =
nullptr;
1187 size_t uploadinfosize = 0;
1188 if (freerdp_assistance_consume_input_and_get_element(buffer, size,
"UPLOADINFO", &uploadinfo,
1190 return freerdp_assistance_parse_uploadinfo(file, uploadinfo, uploadinfosize);
1194 freerdp_assistance_contains_element(buffer, size,
"E", &elen,
nullptr,
nullptr);
1195 if (!estr || (elen == 0))
1197 WLog_ERR(TAG,
"Failed to parse ASSISTANCE file: Neither UPLOADINFO nor <E> found");
1200 if (!update_connectionstring2(file, estr, elen))
1203 if (!freerdp_assistance_parse_connection_string2(file))
1209int freerdp_assistance_parse_file_buffer(rdpAssistanceFile* file,
const char* cbuffer,
size_t size,
1210 const char* password)
1215 WLog_WARN(TAG,
"empty password supplied");
1218 if (!cbuffer || (size == 0))
1220 WLog_WARN(TAG,
"no data supplied [%p, %" PRIuz
"]",
1221 WINPR_CXX_COMPAT_CAST(
const void*, cbuffer), size);
1225 char* abuffer = strndup(cbuffer, size);
1226 const size_t len = strnlen(cbuffer, size);
1228 WLog_WARN(TAG,
"Input data not '\\0' terminated");
1233 const int rc = freerdp_assistance_parse_file_buffer_int(file, abuffer, len + 1, password);
1238int freerdp_assistance_parse_file(rdpAssistanceFile* file,
const char* name,
const char* password)
1241 BYTE* buffer =
nullptr;
1242 size_t readSize = 0;
1249 if (!update_name(file, name))
1252 FILE* fp = winpr_fopen(name,
"r");
1256 WLog_ERR(TAG,
"Failed to open ASSISTANCE file %s ", name);
1260 if (_fseeki64(fp, 0, SEEK_END) < 0)
1262 fileSize.i64 = _ftelli64(fp);
1263 if (_fseeki64(fp, 0, SEEK_SET) < 0)
1266 if (fileSize.i64 < 1)
1268 WLog_ERR(TAG,
"Failed to read ASSISTANCE file %s ", name);
1272 buffer = (BYTE*)malloc(fileSize.s + 2);
1277 readSize = fread(buffer, fileSize.s, 1, fp);
1282 readSize = fileSize.s;
1287 WLog_ERR(TAG,
"Failed to read ASSISTANCE file %s ", name);
1291 buffer[fileSize.s] =
'\0';
1292 buffer[fileSize.s + 1] =
'\0';
1293 status = freerdp_assistance_parse_file_buffer(file, (
char*)buffer, fileSize.s, password);
1301BOOL freerdp_assistance_populate_settings_from_assistance_file(rdpAssistanceFile* file,
1302 rdpSettings* settings)
1307 if (!file->RASessionId || !file->MachineAddresses)
1323 file->ConnectionString2))
1334 if (ArrayList_Count(file->MachineAddresses) < 1)
1337 const char* addr = ArrayList_GetItem(file->MachineAddresses, 0);
1356 const size_t ports = ArrayList_Count(file->MachinePorts);
1357 const size_t addresses = ArrayList_Count(file->MachineAddresses);
1360 if (ports != addresses)
1368 cnv.data = ArrayList_GetItem(file->MachinePorts, 0);
1369 WINPR_ASSERT(cnv.port <= UINT32_MAX);
1373 if (!freerdp_target_net_adresses_reset(settings, ports))
1376 for (
size_t x = 0; x < ports; x++)
1378 cnv.data = ArrayList_GetItem(file->MachinePorts, x);
1379 WINPR_ASSERT(cnv.port <= UINT32_MAX);
1380 const UINT32 port = (UINT32)cnv.port;
1381 if (!freerdp_settings_set_pointer_array(settings, FreeRDP_TargetNetPorts, x, &port))
1384 for (
size_t i = 0; i < addresses; i++)
1386 const char* maddr = ArrayList_GetItem(file->MachineAddresses, i);
1387 if (!freerdp_settings_set_pointer_array(settings, FreeRDP_TargetNetAddresses, i, maddr))
1394static BOOL setup_string(wArrayList* list)
1398 wObject* obj = ArrayList_Object(list);
1406rdpAssistanceFile* freerdp_assistance_file_new(
void)
1408 if (!winpr_InitializeSSL(WINPR_SSL_INIT_DEFAULT))
1411 rdpAssistanceFile* file = calloc(1,
sizeof(rdpAssistanceFile));
1415 file->MachineAddresses = ArrayList_New(FALSE);
1416 file->MachinePorts = ArrayList_New(FALSE);
1417 file->MachineUris = ArrayList_New(FALSE);
1419 if (!file->MachineAddresses || !file->MachinePorts || !file->MachineUris)
1422 if (!setup_string(file->MachineAddresses) || !setup_string(file->MachineUris))
1428 WINPR_PRAGMA_DIAG_PUSH
1429 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
1430 freerdp_assistance_file_free(file);
1431 WINPR_PRAGMA_DIAG_POP
1435void freerdp_assistance_file_free(rdpAssistanceFile* file)
1440 update_password(file,
nullptr);
1441 update_connectionstring2(file,
nullptr, 0);
1442 free(file->filename);
1443 free(file->Username);
1444 free(file->LHTicket);
1445 free(file->RCTicket);
1446 free(file->PassStub);
1447 free(file->ConnectionString1);
1448 free(file->EncryptedLHTicket);
1449 free(file->RASessionId);
1450 free(file->RASpecificParams);
1451 free(file->RASpecificParams2);
1452 free(file->EncryptedPassStub);
1454 ArrayList_Free(file->MachineAddresses);
1455 ArrayList_Free(file->MachinePorts);
1456 ArrayList_Free(file->MachineUris);
1460void freerdp_assistance_print_file(rdpAssistanceFile* file, wLog* log, DWORD level)
1464 WLog_Print(log, level,
"Username: %s", file->Username);
1465 WLog_Print(log, level,
"LHTicket: %s", file->LHTicket);
1466 WLog_Print(log, level,
"RCTicket: %s", file->RCTicket);
1467 WLog_Print(log, level,
"RCTicketEncrypted: %" PRId32, file->RCTicketEncrypted);
1468 WLog_Print(log, level,
"PassStub: %s", file->PassStub);
1469 WLog_Print(log, level,
"DtStart: %" PRIu32, file->DtStart);
1470 WLog_Print(log, level,
"DtLength: %" PRIu32, file->DtLength);
1471 WLog_Print(log, level,
"LowSpeed: %" PRId32, file->LowSpeed);
1472 WLog_Print(log, level,
"RASessionId: %s", file->RASessionId);
1473 WLog_Print(log, level,
"RASpecificParams: %s", file->RASpecificParams);
1474 WLog_Print(log, level,
"RASpecificParams2: %s", file->RASpecificParams2);
1476 for (
size_t x = 0; x < ArrayList_Count(file->MachineAddresses); x++)
1479 const char* uri =
nullptr;
1480 const char* addr = ArrayList_GetItem(file->MachineAddresses, x);
1481 if (x < ArrayList_Count(file->MachinePorts))
1488 cnv.data = ArrayList_GetItem(file->MachinePorts, x);
1489 WINPR_ASSERT(cnv.port <= UINT32_MAX);
1490 port = (UINT32)cnv.port;
1492 if (x < ArrayList_Count(file->MachineUris))
1493 uri = ArrayList_GetItem(file->MachineUris, x);
1495 WLog_Print(log, level,
"MachineAddress [%" PRIuz
": %s", x, addr);
1496 WLog_Print(log, level,
"MachinePort [%" PRIuz
": %" PRIu32, x, port);
1497 WLog_Print(log, level,
"MachineURI [%" PRIuz
": %s", x, uri);
1501BOOL freerdp_assistance_get_encrypted_pass_stub(rdpAssistanceFile* file,
const char** pwd,
1504 if (!file || !pwd || !size)
1507 *pwd = (
const char*)file->EncryptedPassStub;
1508 *size = file->EncryptedPassStubLength;
1512int freerdp_assistance_set_connection_string2(rdpAssistanceFile* file,
const char*
string,
1513 const char* password)
1515 if (!file || !
string || !password)
1518 char* str = _strdup(
string);
1522 if (!update_connectionstring2_nocopy(file, str))
1524 if (!update_password(file, password))
1526 return freerdp_assistance_parse_connection_string2(file);
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_set_bool(rdpSettings *settings, FreeRDP_Settings_Keys_Bool id, BOOL val)
Sets a BOOL settings value.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_set_uint32(rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id, UINT32 val)
Sets a UINT32 settings value.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_set_string(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const char *val)
Sets a string settings value. The param is copied.
This struct contains function pointer to initialize/free objects.
OBJECT_FREE_FN fnObjectFree