20 #include <freerdp/config.h>
24 #include <winpr/wtypes.h>
25 #include <winpr/collections.h>
26 #include <winpr/string.h>
27 #include <winpr/crt.h>
28 #include <winpr/crypto.h>
29 #include <winpr/print.h>
30 #include <winpr/windows.h>
31 #include <winpr/ssl.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")
44 struct 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;
78 static const char* strrstr(
const char* haystack,
size_t len,
const char* needle)
86 char* p = strstr(haystack, needle);
89 if (p > haystack + len)
99 static 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);
113 static 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;
128 static 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;
139 static 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;
150 static 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);
165 static 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);
217 static 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);
254 static 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);
269 static 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);
288 static 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);
325 static BOOL freerdp_assistance_parse_connection_string1(rdpAssistanceFile* file)
327 char* tokens[8] = { 0 };
339 char* str = _strdup(file->RCTicket);
344 const size_t length = strlen(str);
347 for (
size_t i = 0; i < length; i++)
357 tokens[count++] = str;
359 for (
size_t i = 0; i < length; i++)
364 tokens[count++] = &str[i + 1];
368 if (strcmp(tokens[0],
"65538") != 0)
371 if (strcmp(tokens[1],
"1") != 0)
374 if (strcmp(tokens[3],
"*") != 0)
377 if (strcmp(tokens[5],
"*") != 0)
380 if (strcmp(tokens[6],
"*") != 0)
383 file->RASessionId = _strdup(tokens[4]);
385 if (!file->RASessionId)
388 file->RASpecificParams = _strdup(tokens[7]);
390 if (!file->RASpecificParams)
393 if (!freerdp_assistance_parse_address_list(file, tokens[2]))
415 static BOOL freerdp_assistance_parse_attr(
const char** opt,
size_t* plength,
const char* key,
419 WINPR_ASSERT(plength);
427 char bkey[128] = { 0 };
428 const int rc = _snprintf(bkey,
sizeof(bkey),
"%s=\"", key);
429 WINPR_ASSERT(rc > 0);
430 WINPR_ASSERT((
size_t)rc <
sizeof(bkey));
431 if ((rc <= 0) || ((
size_t)rc >=
sizeof(bkey)))
434 char* p = strstr(tag, bkey);
439 char* q = strchr(p,
'"');
443 WLog_ERR(TAG,
"Failed to parse ASSISTANCE file: ConnectionString2 invalid field '%s=%s'",
451 "Failed to parse ASSISTANCE file: ConnectionString2 invalid field "
456 const size_t length = WINPR_ASSERTING_INT_CAST(
size_t, q - p);
463 static BOOL freerdp_assistance_parse_attr_str(
char** opt,
const char* key,
const char* tag)
465 const char* copt = NULL;
467 if (!freerdp_assistance_parse_attr(&copt, &size, key, tag))
469 return update_option(opt, copt, size);
472 static BOOL freerdp_assistance_parse_attr_bool(BOOL* opt,
const char* key,
const char* tag)
474 const char* copt = NULL;
480 if (!freerdp_assistance_parse_attr(&copt, &size, key, tag))
485 *opt = (copt[0] ==
'1');
489 static BOOL freerdp_assistance_parse_attr_uint32(UINT32* opt,
const char* key,
const char* tag)
491 const char* copt = NULL;
497 if (!freerdp_assistance_parse_attr(&copt, &size, key, tag))
500 char buffer[64] = { 0 };
501 if ((!copt && (size > 0)) || (size >=
sizeof(buffer)))
503 WLog_WARN(TAG,
"Invalid UINT32 string '%s' [%" PRIuz
"]", copt, size);
508 strncpy(buffer, copt, size);
511 unsigned long val = strtoul(buffer, NULL, 0);
513 if ((errno != 0) || (val > UINT32_MAX))
515 WLog_ERR(TAG,
"Failed to parse ASSISTANCE file: Invalid value %s", buffer);
524 static char* freerdp_assistance_contains_element(
char* input,
size_t ilen,
const char* key,
525 size_t* plen,
char** pdata,
size_t* pdlen)
531 char bkey[128] = { 0 };
532 const int rc = _snprintf(bkey,
sizeof(bkey),
"<%s", key);
533 WINPR_ASSERT(rc > 0);
534 WINPR_ASSERT((
size_t)rc <
sizeof(bkey));
535 if ((rc < 0) || ((
size_t)rc >=
sizeof(bkey)))
538 char* tag = strstr(input, bkey);
539 if (!tag || (tag > input + ilen))
542 char* data = tag + strnlen(bkey,
sizeof(bkey));
554 "Failed to parse ASSISTANCE file: ConnectionString2 missing delimiter after "
560 char* start = strstr(tag,
">");
562 if (!start || (start > input + ilen))
564 WLog_ERR(TAG,
"Failed to parse ASSISTANCE file: ConnectionString2 missing field %s", bkey);
568 const char* end = start;
569 const char* dend = start - 1;
572 char ekey[128] = { 0 };
573 const int erc = _snprintf(ekey,
sizeof(ekey),
"</%s>", key);
574 WINPR_ASSERT(erc > 0);
575 WINPR_ASSERT((
size_t)erc <
sizeof(ekey));
576 if ((erc <= 0) || ((
size_t)erc >=
sizeof(ekey)))
578 const size_t offset = WINPR_ASSERTING_INT_CAST(
size_t, start - tag);
579 dend = end = strrstr(start, ilen - offset, ekey);
581 end += strnlen(ekey,
sizeof(ekey));
587 "Failed to parse ASSISTANCE file: ConnectionString2 missing end tag for field %s",
592 *plen = WINPR_ASSERTING_INT_CAST(
size_t, end - tag);
597 *pdlen = WINPR_ASSERTING_INT_CAST(
size_t, dend - data);
606 static BOOL freerdp_assistance_consume_input_and_get_element(
char* input,
const char* key,
607 char** element,
size_t* elen)
611 WINPR_ASSERT(element);
617 char* tag = freerdp_assistance_contains_element(input, strlen(input), key, &len, &data, &dlen);
621 char* end = data + dlen;
629 static BOOL freerdp_assistance_get_element(
char* input,
size_t ilen,
const char* key,
630 char** element,
size_t* elen)
634 WINPR_ASSERT(element);
640 char* tag = freerdp_assistance_contains_element(input, ilen, key, &len, &data, &dlen);
644 if (tag + len > input + ilen)
647 char* end = tag + len;
649 *elen = WINPR_ASSERTING_INT_CAST(
size_t, end - data + 1);
653 static BOOL freerdp_assistance_parse_all_elements_of(rdpAssistanceFile* file,
char* data,
654 size_t len,
const char* key,
655 BOOL (*fkt)(rdpAssistanceFile* file,
656 char* data,
size_t len))
661 while (freerdp_assistance_get_element(data, len, key, &val, &vlen))
664 len = strnlen(data, len);
667 val[vlen - 1] =
'\0';
669 if (!fkt(file, val, vlen))
677 static BOOL freerdp_assistance_parse_all_elements_of_l(rdpAssistanceFile* file,
char* data,
681 const char* n = NULL;
682 const char* u = NULL;
685 if (!freerdp_assistance_parse_attr_uint32(&p,
"P", data))
687 if (!freerdp_assistance_parse_attr(&n, &nlen,
"N", data))
689 if (!freerdp_assistance_parse_attr(&u, &ulen,
"U", data))
694 if (!append_address_to_list(file->MachineAddresses, n, nlen))
696 if (!ArrayList_Append(file->MachinePorts, (
void*)(uintptr_t)p))
701 if (!append_address_to_list(file->MachineAddresses, u, ulen))
703 if (!ArrayList_Append(file->MachinePorts, (
void*)(uintptr_t)p))
709 static BOOL freerdp_assistance_parse_all_elements_of_t(rdpAssistanceFile* file,
char* data,
714 if (!freerdp_assistance_parse_attr_uint32(&
id,
"ID", data))
716 if (!freerdp_assistance_parse_attr_uint32(&sid,
"SID", data))
718 WLog_DBG(TAG,
"transport id=%" PRIu32
", sid=%" PRIu32,
id, sid);
719 return freerdp_assistance_parse_all_elements_of(file, data, len,
"L",
720 freerdp_assistance_parse_all_elements_of_l);
723 static BOOL freerdp_assistance_parse_all_elements_of_c(rdpAssistanceFile* file,
char* data,
726 return freerdp_assistance_parse_all_elements_of(file, data, len,
"T",
727 freerdp_assistance_parse_all_elements_of_t);
730 static BOOL freerdp_assistance_parse_find_elements_of_c(rdpAssistanceFile* file,
char* data,
733 return freerdp_assistance_parse_all_elements_of(file, data, len,
"C",
734 freerdp_assistance_parse_all_elements_of_c);
737 static BOOL freerdp_assistance_parse_connection_string2(rdpAssistanceFile* file)
743 if (!file->ConnectionString2)
746 char* str = _strdup(file->ConnectionString2);
752 if (!freerdp_assistance_consume_input_and_get_element(str,
"E", &e, &elen))
755 if (!e || (elen == 0))
760 if (!freerdp_assistance_get_element(e, elen,
"A", &a, &alen))
763 if (!a || (alen == 0))
766 if (!freerdp_assistance_parse_find_elements_of_c(file, e, elen))
773 if (!freerdp_assistance_parse_attr_str(&file->RASpecificParams,
"KH", a))
776 if (!freerdp_assistance_parse_attr_str(&file->RASpecificParams2,
"KH2", a))
779 if (!freerdp_assistance_parse_attr_str(&file->RASessionId,
"ID", a))
788 char* freerdp_assistance_construct_expert_blob(
const char* name,
const char* pass)
793 const size_t nameLength = strlen(name) + strlen(
"NAME=");
794 const size_t passLength = strlen(pass) + strlen(
"PASS=");
795 const size_t size = nameLength + passLength + 64;
796 char* ExpertBlob = (
char*)calloc(1, size);
801 (void)sprintf_s(ExpertBlob, size,
"%" PRIuz
";NAME=%s%" PRIuz
";PASS=%s", nameLength, name,
806 char* freerdp_assistance_generate_pass_stub(DWORD flags)
809 char* passStub = NULL;
810 char set1[64] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789*_";
811 char set2[12] =
"!@#$&^*()-+=";
812 char set3[10] =
"0123456789";
813 char set4[26] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
814 char set5[26] =
"abcdefghijklmnopqrstuvwxyz";
815 passStub = (
char*)malloc(15);
831 winpr_RAND(nums,
sizeof(nums));
832 passStub[0] = set1[nums[0] %
sizeof(set1)];
833 passStub[1] = set2[nums[1] %
sizeof(set2)];
834 passStub[2] = set3[nums[2] %
sizeof(set3)];
835 passStub[3] = set4[nums[3] %
sizeof(set4)];
836 passStub[4] = set5[nums[4] %
sizeof(set5)];
837 passStub[5] = set1[nums[5] %
sizeof(set1)];
838 passStub[6] = set1[nums[6] %
sizeof(set1)];
839 passStub[7] = set1[nums[7] %
sizeof(set1)];
840 passStub[8] = set1[nums[8] %
sizeof(set1)];
841 passStub[9] = set1[nums[9] %
sizeof(set1)];
842 passStub[10] = set1[nums[10] %
sizeof(set1)];
843 passStub[11] = set1[nums[11] %
sizeof(set1)];
844 passStub[12] = set1[nums[12] %
sizeof(set1)];
845 passStub[13] = set1[nums[13] %
sizeof(set1)];
850 BYTE* freerdp_assistance_encrypt_pass_stub(
const char* password,
const char* passStub,
851 size_t* pEncryptedSize)
854 size_t cbPasswordW = 0;
855 size_t cbPassStubW = 0;
856 BYTE PasswordHash[WINPR_MD5_DIGEST_LENGTH] = { 0 };
857 WINPR_RC4_CTX* rc4Ctx = NULL;
861 WCHAR* PasswordW = ConvertUtf8ToWCharAlloc(password, &cbPasswordW);
862 WCHAR* PassStubW = ConvertUtf8ToWCharAlloc(passStub, &cbPassStubW);
864 cbPasswordW = (cbPasswordW) *
sizeof(WCHAR);
865 cbPassStubW = (cbPassStubW) *
sizeof(WCHAR);
866 const size_t EncryptedSize = cbPassStubW + 4;
868 if (!PasswordW || !PassStubW)
871 if (!winpr_Digest(WINPR_MD_MD5, (BYTE*)PasswordW, cbPasswordW, (BYTE*)PasswordHash,
872 sizeof(PasswordHash)))
875 pbIn = (BYTE*)calloc(1, EncryptedSize);
876 pbOut = (BYTE*)calloc(1, EncryptedSize);
881 WINPR_ASSERT(cbPasswordW <= UINT32_MAX);
882 winpr_Data_Write_UINT32(pbIn, (UINT32)cbPassStubW);
883 CopyMemory(&pbIn[4], PassStubW, cbPassStubW);
884 rc4Ctx = winpr_RC4_New(PasswordHash,
sizeof(PasswordHash));
888 WLog_ERR(TAG,
"winpr_Cipher_New failure");
892 rc = winpr_RC4_Update(rc4Ctx, EncryptedSize, pbIn, pbOut);
896 WLog_ERR(TAG,
"winpr_Cipher_Update failure");
901 winpr_RC4_Free(rc4Ctx);
908 *pEncryptedSize = EncryptedSize;
912 static BOOL freerdp_assistance_decrypt2(rdpAssistanceFile* file)
916 size_t cbPasswordW = 0;
918 WINPR_CIPHER_CTX* aesDec = NULL;
919 WCHAR* PasswordW = NULL;
925 BYTE DerivedKey[WINPR_AES_BLOCK_SIZE] = { 0 };
926 BYTE InitializationVector[WINPR_AES_BLOCK_SIZE] = { 0 };
927 BYTE PasswordHash[WINPR_SHA1_DIGEST_LENGTH] = { 0 };
934 PasswordW = ConvertUtf8ToWCharAlloc(file->password, &cbPasswordW);
937 WLog_ERR(TAG,
"Failed to parse ASSISTANCE file: Conversion from UCS2 to UTF8 failed");
941 cbPasswordW = (cbPasswordW) *
sizeof(WCHAR);
943 if (!winpr_Digest(WINPR_MD_SHA1, (BYTE*)PasswordW, cbPasswordW, PasswordHash,
944 sizeof(PasswordHash)))
947 if (!freerdp_assistance_crypt_derive_key_sha1(PasswordHash,
sizeof(PasswordHash), DerivedKey,
952 winpr_Cipher_NewEx(WINPR_CIPHER_AES_128_CBC, WINPR_DECRYPT, DerivedKey,
sizeof(DerivedKey),
953 InitializationVector,
sizeof(InitializationVector));
959 cbIn = file->EncryptedLHTicketLength;
960 pbIn = file->EncryptedLHTicket;
961 pbOut = (BYTE*)calloc(1, cbIn + WINPR_AES_BLOCK_SIZE + 2);
966 if (!winpr_Cipher_Update(aesDec, pbIn, cbIn, pbOut, &cbOut))
969 if (!winpr_Cipher_Final(aesDec, pbOut + cbOut, &cbFinal))
971 WLog_ERR(TAG,
"winpr_Cipher_Final failure");
985 cchOutW = cbOut /
sizeof(WCHAR);
987 if (!update_connectionstring2_wchar(file, cnv.wc, cchOutW))
989 WLog_ERR(TAG,
"Failed to parse ASSISTANCE file: Conversion from UCS2 to UTF8 failed");
993 if (!freerdp_assistance_parse_connection_string2(file))
998 winpr_Cipher_Free(aesDec);
1001 WLog_DBG(TAG,
"freerdp_assistance_parse_connection_string2: %d", status);
1005 BYTE* freerdp_assistance_hex_string_to_bin(
const void* raw,
size_t* size)
1007 BYTE* buffer = NULL;
1011 const size_t length = strlen(raw);
1012 buffer = calloc(length,
sizeof(BYTE));
1015 const size_t rc = winpr_HexStringToBinBuffer(raw, length, buffer, length);
1025 char* freerdp_assistance_bin_to_hex_string(
const void* raw,
size_t size)
1027 return winpr_BinToHexString(raw, size, FALSE);
1030 static int freerdp_assistance_parse_uploadinfo(rdpAssistanceFile* file,
char* uploadinfo,
1031 size_t uploadinfosize)
1033 const char escalated[9] =
"Escalated";
1034 const size_t esclen =
sizeof(escalated);
1035 const char* typestr = NULL;
1038 if (!uploadinfo || (uploadinfosize == 0))
1041 if (strnlen(uploadinfo, uploadinfosize) == uploadinfosize)
1043 WLog_WARN(TAG,
"UPLOADINFOR string is not '\0' terminated");
1047 if (!freerdp_assistance_parse_attr(&typestr, &typelen,
"TYPE", uploadinfo))
1050 if ((typelen != esclen) || (strncmp(typestr, escalated, esclen) != 0))
1053 "Failed to parse ASSISTANCE file: Missing or invalid UPLOADINFO TYPE '%s' [%" PRIuz
1059 char* uploaddata = NULL;
1060 size_t uploaddatasize = 0;
1061 if (!freerdp_assistance_consume_input_and_get_element(uploadinfo,
"UPLOADDATA", &uploaddata,
1066 if (!freerdp_assistance_parse_attr_str(&file->Username,
"USERNAME", uploaddata))
1070 if (!freerdp_assistance_parse_attr_str(&file->LHTicket,
"LHTICKET", uploaddata))
1074 if (!freerdp_assistance_parse_attr_str(&file->RCTicket,
"RCTICKET", uploaddata))
1078 if (!freerdp_assistance_parse_attr_bool(&file->RCTicketEncrypted,
"RCTICKETENCRYPTED",
1083 if (!freerdp_assistance_parse_attr_str(&file->PassStub,
"PassStub", uploaddata))
1088 const char* amp =
"&";
1089 char* passtub = strstr(file->PassStub, amp);
1092 const char* end = passtub + 5;
1093 const size_t len = strlen(end);
1094 memmove(&passtub[1], end, len + 1);
1095 passtub = strstr(passtub, amp);
1100 if (!freerdp_assistance_parse_attr_uint32(&file->DtStart,
"DtStart", uploaddata))
1104 if (!freerdp_assistance_parse_attr_uint32(&file->DtLength,
"DtLength", uploaddata))
1108 if (!freerdp_assistance_parse_attr_bool(&file->LowSpeed,
"L", uploaddata))
1111 file->Type = (file->LHTicket) ? 2 : 1;
1118 file->EncryptedLHTicket = freerdp_assistance_hex_string_to_bin(
1119 file->LHTicket, &file->EncryptedLHTicketLength);
1121 if (!freerdp_assistance_decrypt2(file))
1128 if (!freerdp_assistance_parse_connection_string1(file))
1139 WLog_ERR(TAG,
"freerdp_assistance_parse_connection_string1 failure: %d", status);
1143 file->EncryptedPassStub = freerdp_assistance_encrypt_pass_stub(file->password, file->PassStub,
1144 &file->EncryptedPassStubLength);
1146 if (!file->EncryptedPassStub)
1152 static int freerdp_assistance_parse_file_buffer_int(rdpAssistanceFile* file,
char* buffer,
1153 size_t size,
const char* password)
1156 WINPR_ASSERT(buffer);
1157 WINPR_ASSERT(size > 0);
1159 if (!update_password(file, password))
1162 char* uploadinfo = NULL;
1163 size_t uploadinfosize = 0;
1164 if (freerdp_assistance_consume_input_and_get_element(buffer,
"UPLOADINFO", &uploadinfo,
1166 return freerdp_assistance_parse_uploadinfo(file, uploadinfo, uploadinfosize);
1169 const char* estr = freerdp_assistance_contains_element(buffer, size,
"E", &elen, NULL, NULL);
1170 if (!estr || (elen == 0))
1172 WLog_ERR(TAG,
"Failed to parse ASSISTANCE file: Neither UPLOADINFO nor <E> found");
1175 if (!update_connectionstring2(file, estr, elen))
1178 if (!freerdp_assistance_parse_connection_string2(file))
1184 int freerdp_assistance_parse_file_buffer(rdpAssistanceFile* file,
const char* cbuffer,
size_t size,
1185 const char* password)
1190 WLog_WARN(TAG,
"empty password supplied");
1193 if (!cbuffer || (size == 0))
1195 WLog_WARN(TAG,
"no data supplied [%p, %" PRIuz
"]", cbuffer, size);
1199 char* abuffer = strndup(cbuffer, size);
1200 const size_t len = strnlen(cbuffer, size);
1202 WLog_WARN(TAG,
"Input data not '\0' terminated");
1207 const int rc = freerdp_assistance_parse_file_buffer_int(file, abuffer, len + 1, password);
1212 int freerdp_assistance_parse_file(rdpAssistanceFile* file,
const char* name,
const char* password)
1215 BYTE* buffer = NULL;
1217 size_t readSize = 0;
1224 if (!update_name(file, name))
1227 fp = winpr_fopen(name,
"r");
1231 WLog_ERR(TAG,
"Failed to open ASSISTANCE file %s ", name);
1235 (void)_fseeki64(fp, 0, SEEK_END);
1236 fileSize.i64 = _ftelli64(fp);
1237 (void)_fseeki64(fp, 0, SEEK_SET);
1239 if (fileSize.i64 < 1)
1241 WLog_ERR(TAG,
"Failed to read ASSISTANCE file %s ", name);
1246 buffer = (BYTE*)malloc(fileSize.s + 2);
1254 readSize = fread(buffer, fileSize.s, 1, fp);
1259 readSize = fileSize.s;
1266 WLog_ERR(TAG,
"Failed to read ASSISTANCE file %s ", name);
1272 buffer[fileSize.s] =
'\0';
1273 buffer[fileSize.s + 1] =
'\0';
1274 status = freerdp_assistance_parse_file_buffer(file, (
char*)buffer, fileSize.s, password);
1279 BOOL freerdp_assistance_populate_settings_from_assistance_file(rdpAssistanceFile* file,
1280 rdpSettings* settings)
1285 if (!file->RASessionId || !file->MachineAddresses)
1301 file->ConnectionString2))
1312 if (ArrayList_Count(file->MachineAddresses) < 1)
1315 const char* addr = ArrayList_GetItem(file->MachineAddresses, 0);
1334 const size_t ports = ArrayList_Count(file->MachinePorts);
1335 const size_t addresses = ArrayList_Count(file->MachineAddresses);
1338 if (ports != addresses)
1346 cnv.data = ArrayList_GetItem(file->MachinePorts, 0);
1347 WINPR_ASSERT(cnv.port <= UINT32_MAX);
1351 if (!freerdp_target_net_adresses_reset(settings, ports))
1354 for (
size_t x = 0; x < ports; x++)
1356 cnv.data = ArrayList_GetItem(file->MachinePorts, x);
1357 WINPR_ASSERT(cnv.port <= UINT32_MAX);
1358 const UINT32 port = (UINT32)cnv.port;
1359 if (!freerdp_settings_set_pointer_array(settings, FreeRDP_TargetNetPorts, x, &port))
1362 for (
size_t i = 0; i < addresses; i++)
1364 const char* maddr = ArrayList_GetItem(file->MachineAddresses, i);
1365 if (!freerdp_settings_set_pointer_array(settings, FreeRDP_TargetNetAddresses, i, maddr))
1372 static BOOL setup_string(wArrayList* list)
1376 wObject* obj = ArrayList_Object(list);
1379 obj->fnObjectFree = free;
1384 rdpAssistanceFile* freerdp_assistance_file_new(
void)
1386 winpr_InitializeSSL(WINPR_SSL_INIT_DEFAULT);
1387 rdpAssistanceFile* file = calloc(1,
sizeof(rdpAssistanceFile));
1391 file->MachineAddresses = ArrayList_New(FALSE);
1392 file->MachinePorts = ArrayList_New(FALSE);
1393 file->MachineUris = ArrayList_New(FALSE);
1395 if (!file->MachineAddresses || !file->MachinePorts || !file->MachineUris)
1398 if (!setup_string(file->MachineAddresses) || !setup_string(file->MachineUris))
1404 WINPR_PRAGMA_DIAG_PUSH
1405 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
1406 freerdp_assistance_file_free(file);
1407 WINPR_PRAGMA_DIAG_POP
1411 void freerdp_assistance_file_free(rdpAssistanceFile* file)
1416 update_password(file, NULL);
1417 update_connectionstring2(file, NULL, 0);
1418 free(file->filename);
1419 free(file->Username);
1420 free(file->LHTicket);
1421 free(file->RCTicket);
1422 free(file->PassStub);
1423 free(file->ConnectionString1);
1424 free(file->EncryptedLHTicket);
1425 free(file->RASessionId);
1426 free(file->RASpecificParams);
1427 free(file->RASpecificParams2);
1428 free(file->EncryptedPassStub);
1430 ArrayList_Free(file->MachineAddresses);
1431 ArrayList_Free(file->MachinePorts);
1432 ArrayList_Free(file->MachineUris);
1436 void freerdp_assistance_print_file(rdpAssistanceFile* file, wLog* log, DWORD level)
1440 WLog_Print(log, level,
"Username: %s", file->Username);
1441 WLog_Print(log, level,
"LHTicket: %s", file->LHTicket);
1442 WLog_Print(log, level,
"RCTicket: %s", file->RCTicket);
1443 WLog_Print(log, level,
"RCTicketEncrypted: %" PRId32, file->RCTicketEncrypted);
1444 WLog_Print(log, level,
"PassStub: %s", file->PassStub);
1445 WLog_Print(log, level,
"DtStart: %" PRIu32, file->DtStart);
1446 WLog_Print(log, level,
"DtLength: %" PRIu32, file->DtLength);
1447 WLog_Print(log, level,
"LowSpeed: %" PRId32, file->LowSpeed);
1448 WLog_Print(log, level,
"RASessionId: %s", file->RASessionId);
1449 WLog_Print(log, level,
"RASpecificParams: %s", file->RASpecificParams);
1450 WLog_Print(log, level,
"RASpecificParams2: %s", file->RASpecificParams2);
1452 for (
size_t x = 0; x < ArrayList_Count(file->MachineAddresses); x++)
1455 const char* uri = NULL;
1456 const char* addr = ArrayList_GetItem(file->MachineAddresses, x);
1457 if (x < ArrayList_Count(file->MachinePorts))
1464 cnv.data = ArrayList_GetItem(file->MachinePorts, x);
1465 WINPR_ASSERT(cnv.port <= UINT32_MAX);
1466 port = (UINT32)cnv.port;
1468 if (x < ArrayList_Count(file->MachineUris))
1469 uri = ArrayList_GetItem(file->MachineUris, x);
1471 WLog_Print(log, level,
"MachineAddress [%" PRIdz
": %s", x, addr);
1472 WLog_Print(log, level,
"MachinePort [%" PRIdz
": %" PRIu32, x, port);
1473 WLog_Print(log, level,
"MachineURI [%" PRIdz
": %s", x, uri);
1477 BOOL freerdp_assistance_get_encrypted_pass_stub(rdpAssistanceFile* file,
const char** pwd,
1480 if (!file || !pwd || !size)
1483 *pwd = (
const char*)file->EncryptedPassStub;
1484 *size = file->EncryptedPassStubLength;
1488 int freerdp_assistance_set_connection_string2(rdpAssistanceFile* file,
const char*
string,
1489 const char* password)
1491 if (!file || !
string || !password)
1494 char* str = _strdup(
string);
1498 if (!update_connectionstring2_nocopy(file, str))
1500 if (!update_password(file, password))
1502 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.