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 = 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 (size >=
sizeof(buffer))
503 WLog_WARN(TAG,
"Invalid UINT32 string '%s' [%" PRIuz
"]", copt, size);
507 strncpy(buffer, copt, size);
509 unsigned long val = strtoul(buffer, NULL, 0);
511 if ((errno != 0) || (val > UINT32_MAX))
513 WLog_ERR(TAG,
"Failed to parse ASSISTANCE file: Invalid value %s", buffer);
522 static char* freerdp_assistance_contains_element(
char* input,
size_t ilen,
const char* key,
523 size_t* plen,
char** pdata,
size_t* pdlen)
529 char bkey[128] = { 0 };
530 const int rc = _snprintf(bkey,
sizeof(bkey),
"<%s", key);
531 WINPR_ASSERT(rc > 0);
532 WINPR_ASSERT((
size_t)rc <
sizeof(bkey));
533 if ((rc < 0) || ((
size_t)rc >=
sizeof(bkey)))
536 char* tag = strstr(input, bkey);
537 if (!tag || (tag > input + ilen))
540 char* data = tag + strnlen(bkey,
sizeof(bkey));
552 "Failed to parse ASSISTANCE file: ConnectionString2 missing delimiter after "
558 char* start = strstr(tag,
">");
560 if (!start || (start > input + ilen))
562 WLog_ERR(TAG,
"Failed to parse ASSISTANCE file: ConnectionString2 missing field %s", bkey);
566 const char* end = start;
567 const char* dend = start - 1;
570 char ekey[128] = { 0 };
571 const int erc = _snprintf(ekey,
sizeof(ekey),
"</%s>", key);
572 WINPR_ASSERT(erc > 0);
573 WINPR_ASSERT((
size_t)erc <
sizeof(ekey));
574 if ((erc <= 0) || ((
size_t)erc >=
sizeof(ekey)))
576 const size_t offset = start - tag;
577 dend = end = strrstr(start, ilen - offset, ekey);
579 end += strnlen(ekey,
sizeof(ekey));
585 "Failed to parse ASSISTANCE file: ConnectionString2 missing end tag for field %s",
595 *pdlen = dend - data;
604 static BOOL freerdp_assistance_consume_input_and_get_element(
char* input,
const char* key,
605 char** element,
size_t* elen)
609 WINPR_ASSERT(element);
615 char* tag = freerdp_assistance_contains_element(input, strlen(input), key, &len, &data, &dlen);
619 char* end = data + dlen;
627 static BOOL freerdp_assistance_get_element(
char* input,
size_t ilen,
const char* key,
628 char** element,
size_t* elen)
632 WINPR_ASSERT(element);
638 char* tag = freerdp_assistance_contains_element(input, ilen, key, &len, &data, &dlen);
642 if (tag + len > input + ilen)
645 char* end = tag + len;
647 *elen = end - data + 1;
651 static BOOL freerdp_assistance_parse_all_elements_of(rdpAssistanceFile* file,
char* data,
652 size_t len,
const char* key,
653 BOOL (*fkt)(rdpAssistanceFile* file,
654 char* data,
size_t len))
659 while (freerdp_assistance_get_element(data, len, key, &val, &vlen))
662 len = strnlen(data, len);
665 val[vlen - 1] =
'\0';
667 if (!fkt(file, val, vlen))
675 static BOOL freerdp_assistance_parse_all_elements_of_l(rdpAssistanceFile* file,
char* data,
679 const char* n = NULL;
680 const char* u = NULL;
683 if (!freerdp_assistance_parse_attr_uint32(&p,
"P", data))
685 if (!freerdp_assistance_parse_attr(&n, &nlen,
"N", data))
687 if (!freerdp_assistance_parse_attr(&u, &ulen,
"U", data))
692 if (!append_address_to_list(file->MachineAddresses, n, nlen))
694 if (!ArrayList_Append(file->MachinePorts, (
void*)(uintptr_t)p))
699 if (!append_address_to_list(file->MachineAddresses, u, ulen))
701 if (!ArrayList_Append(file->MachinePorts, (
void*)(uintptr_t)p))
707 static BOOL freerdp_assistance_parse_all_elements_of_t(rdpAssistanceFile* file,
char* data,
712 if (!freerdp_assistance_parse_attr_uint32(&
id,
"ID", data))
714 if (!freerdp_assistance_parse_attr_uint32(&sid,
"SID", data))
716 WLog_DBG(TAG,
"transport id=%" PRIu32
", sid=%" PRIu32,
id, sid);
717 return freerdp_assistance_parse_all_elements_of(file, data, len,
"L",
718 freerdp_assistance_parse_all_elements_of_l);
721 static BOOL freerdp_assistance_parse_all_elements_of_c(rdpAssistanceFile* file,
char* data,
724 return freerdp_assistance_parse_all_elements_of(file, data, len,
"T",
725 freerdp_assistance_parse_all_elements_of_t);
728 static BOOL freerdp_assistance_parse_find_elements_of_c(rdpAssistanceFile* file,
char* data,
731 return freerdp_assistance_parse_all_elements_of(file, data, len,
"C",
732 freerdp_assistance_parse_all_elements_of_c);
735 static BOOL freerdp_assistance_parse_connection_string2(rdpAssistanceFile* file)
741 if (!file->ConnectionString2)
744 char* str = _strdup(file->ConnectionString2);
750 if (!freerdp_assistance_consume_input_and_get_element(str,
"E", &e, &elen))
753 if (!e || (elen == 0))
758 if (!freerdp_assistance_get_element(e, elen,
"A", &a, &alen))
761 if (!a || (alen == 0))
764 if (!freerdp_assistance_parse_find_elements_of_c(file, e, elen))
771 if (!freerdp_assistance_parse_attr_str(&file->RASpecificParams,
"KH", a))
774 if (!freerdp_assistance_parse_attr_str(&file->RASpecificParams2,
"KH2", a))
777 if (!freerdp_assistance_parse_attr_str(&file->RASessionId,
"ID", a))
786 char* freerdp_assistance_construct_expert_blob(
const char* name,
const char* pass)
791 const size_t nameLength = strlen(name) + strlen(
"NAME=");
792 const size_t passLength = strlen(pass) + strlen(
"PASS=");
793 const size_t size = nameLength + passLength + 64;
794 char* ExpertBlob = (
char*)calloc(1, size);
799 (void)sprintf_s(ExpertBlob, size,
"%" PRIuz
";NAME=%s%" PRIuz
";PASS=%s", nameLength, name,
804 char* freerdp_assistance_generate_pass_stub(DWORD flags)
807 char* passStub = NULL;
808 char set1[64] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789*_";
809 char set2[12] =
"!@#$&^*()-+=";
810 char set3[10] =
"0123456789";
811 char set4[26] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
812 char set5[26] =
"abcdefghijklmnopqrstuvwxyz";
813 passStub = (
char*)malloc(15);
829 winpr_RAND(nums,
sizeof(nums));
830 passStub[0] = set1[nums[0] %
sizeof(set1)];
831 passStub[1] = set2[nums[1] %
sizeof(set2)];
832 passStub[2] = set3[nums[2] %
sizeof(set3)];
833 passStub[3] = set4[nums[3] %
sizeof(set4)];
834 passStub[4] = set5[nums[4] %
sizeof(set5)];
835 passStub[5] = set1[nums[5] %
sizeof(set1)];
836 passStub[6] = set1[nums[6] %
sizeof(set1)];
837 passStub[7] = set1[nums[7] %
sizeof(set1)];
838 passStub[8] = set1[nums[8] %
sizeof(set1)];
839 passStub[9] = set1[nums[9] %
sizeof(set1)];
840 passStub[10] = set1[nums[10] %
sizeof(set1)];
841 passStub[11] = set1[nums[11] %
sizeof(set1)];
842 passStub[12] = set1[nums[12] %
sizeof(set1)];
843 passStub[13] = set1[nums[13] %
sizeof(set1)];
848 BYTE* freerdp_assistance_encrypt_pass_stub(
const char* password,
const char* passStub,
849 size_t* pEncryptedSize)
852 size_t cbPasswordW = 0;
853 size_t cbPassStubW = 0;
854 BYTE PasswordHash[WINPR_MD5_DIGEST_LENGTH] = { 0 };
855 WINPR_RC4_CTX* rc4Ctx = NULL;
859 WCHAR* PasswordW = ConvertUtf8ToWCharAlloc(password, &cbPasswordW);
860 WCHAR* PassStubW = ConvertUtf8ToWCharAlloc(passStub, &cbPassStubW);
862 cbPasswordW = (cbPasswordW) *
sizeof(WCHAR);
863 cbPassStubW = (cbPassStubW) *
sizeof(WCHAR);
864 const size_t EncryptedSize = cbPassStubW + 4;
866 if (!PasswordW || !PassStubW)
869 if (!winpr_Digest(WINPR_MD_MD5, (BYTE*)PasswordW, cbPasswordW, (BYTE*)PasswordHash,
870 sizeof(PasswordHash)))
873 pbIn = (BYTE*)calloc(1, EncryptedSize);
874 pbOut = (BYTE*)calloc(1, EncryptedSize);
879 *((UINT32*)pbIn) = (UINT32)cbPassStubW;
880 CopyMemory(&pbIn[4], PassStubW, cbPassStubW);
881 rc4Ctx = winpr_RC4_New(PasswordHash,
sizeof(PasswordHash));
885 WLog_ERR(TAG,
"winpr_Cipher_New failure");
889 rc = winpr_RC4_Update(rc4Ctx, EncryptedSize, pbIn, pbOut);
893 WLog_ERR(TAG,
"winpr_Cipher_Update failure");
898 winpr_RC4_Free(rc4Ctx);
905 *pEncryptedSize = EncryptedSize;
909 static BOOL freerdp_assistance_decrypt2(rdpAssistanceFile* file)
913 size_t cbPasswordW = 0;
915 WINPR_CIPHER_CTX* aesDec = NULL;
916 WCHAR* PasswordW = NULL;
922 BYTE DerivedKey[WINPR_AES_BLOCK_SIZE] = { 0 };
923 BYTE InitializationVector[WINPR_AES_BLOCK_SIZE] = { 0 };
924 BYTE PasswordHash[WINPR_SHA1_DIGEST_LENGTH] = { 0 };
931 PasswordW = ConvertUtf8ToWCharAlloc(file->password, &cbPasswordW);
934 WLog_ERR(TAG,
"Failed to parse ASSISTANCE file: Conversion from UCS2 to UTF8 failed");
938 cbPasswordW = (cbPasswordW) *
sizeof(WCHAR);
940 if (!winpr_Digest(WINPR_MD_SHA1, (BYTE*)PasswordW, cbPasswordW, PasswordHash,
941 sizeof(PasswordHash)))
944 if (!freerdp_assistance_crypt_derive_key_sha1(PasswordHash,
sizeof(PasswordHash), DerivedKey,
949 winpr_Cipher_NewEx(WINPR_CIPHER_AES_128_CBC, WINPR_DECRYPT, DerivedKey,
sizeof(DerivedKey),
950 InitializationVector,
sizeof(InitializationVector));
956 cbIn = file->EncryptedLHTicketLength;
957 pbIn = file->EncryptedLHTicket;
958 pbOut = (BYTE*)calloc(1, cbIn + WINPR_AES_BLOCK_SIZE + 2);
963 if (!winpr_Cipher_Update(aesDec, pbIn, cbIn, pbOut, &cbOut))
966 if (!winpr_Cipher_Final(aesDec, pbOut + cbOut, &cbFinal))
968 WLog_ERR(TAG,
"winpr_Cipher_Final failure");
982 cchOutW = cbOut /
sizeof(WCHAR);
984 if (!update_connectionstring2_wchar(file, cnv.wc, cchOutW))
986 WLog_ERR(TAG,
"Failed to parse ASSISTANCE file: Conversion from UCS2 to UTF8 failed");
990 if (!freerdp_assistance_parse_connection_string2(file))
995 winpr_Cipher_Free(aesDec);
998 WLog_DBG(TAG,
"freerdp_assistance_parse_connection_string2: %d", status);
1002 BYTE* freerdp_assistance_hex_string_to_bin(
const void* raw,
size_t* size)
1004 BYTE* buffer = NULL;
1008 const size_t length = strlen(raw);
1009 buffer = calloc(length,
sizeof(BYTE));
1012 const size_t rc = winpr_HexStringToBinBuffer(raw, length, buffer, length);
1022 char* freerdp_assistance_bin_to_hex_string(
const void* raw,
size_t size)
1024 return winpr_BinToHexString(raw, size, FALSE);
1027 static int freerdp_assistance_parse_uploadinfo(rdpAssistanceFile* file,
char* uploadinfo,
1028 size_t uploadinfosize)
1030 const char escalated[9] =
"Escalated";
1031 const size_t esclen =
sizeof(escalated);
1032 const char* typestr = NULL;
1035 if (!uploadinfo || (uploadinfosize == 0))
1038 if (strnlen(uploadinfo, uploadinfosize) == uploadinfosize)
1040 WLog_WARN(TAG,
"UPLOADINFOR string is not '\0' terminated");
1044 if (!freerdp_assistance_parse_attr(&typestr, &typelen,
"TYPE", uploadinfo))
1047 if ((typelen != esclen) || (strncmp(typestr, escalated, esclen) != 0))
1050 "Failed to parse ASSISTANCE file: Missing or invalid UPLOADINFO TYPE '%s' [%" PRIuz
1056 char* uploaddata = NULL;
1057 size_t uploaddatasize = 0;
1058 if (!freerdp_assistance_consume_input_and_get_element(uploadinfo,
"UPLOADDATA", &uploaddata,
1063 if (!freerdp_assistance_parse_attr_str(&file->Username,
"USERNAME", uploaddata))
1067 if (!freerdp_assistance_parse_attr_str(&file->LHTicket,
"LHTICKET", uploaddata))
1071 if (!freerdp_assistance_parse_attr_str(&file->RCTicket,
"RCTICKET", uploaddata))
1075 if (!freerdp_assistance_parse_attr_bool(&file->RCTicketEncrypted,
"RCTICKETENCRYPTED",
1080 if (!freerdp_assistance_parse_attr_str(&file->PassStub,
"PassStub", uploaddata))
1085 const char* amp =
"&";
1086 char* passtub = strstr(file->PassStub, amp);
1089 const char* end = passtub + 5;
1090 const size_t len = strlen(end);
1091 memmove(&passtub[1], end, len + 1);
1092 passtub = strstr(passtub, amp);
1097 if (!freerdp_assistance_parse_attr_uint32(&file->DtStart,
"DtStart", uploaddata))
1101 if (!freerdp_assistance_parse_attr_uint32(&file->DtLength,
"DtLength", uploaddata))
1105 if (!freerdp_assistance_parse_attr_bool(&file->LowSpeed,
"L", uploaddata))
1108 file->Type = (file->LHTicket) ? 2 : 1;
1115 file->EncryptedLHTicket = freerdp_assistance_hex_string_to_bin(
1116 file->LHTicket, &file->EncryptedLHTicketLength);
1118 if (!freerdp_assistance_decrypt2(file))
1125 if (!freerdp_assistance_parse_connection_string1(file))
1136 WLog_ERR(TAG,
"freerdp_assistance_parse_connection_string1 failure: %d", status);
1140 file->EncryptedPassStub = freerdp_assistance_encrypt_pass_stub(file->password, file->PassStub,
1141 &file->EncryptedPassStubLength);
1143 if (!file->EncryptedPassStub)
1149 static int freerdp_assistance_parse_file_buffer_int(rdpAssistanceFile* file,
char* buffer,
1150 size_t size,
const char* password)
1153 WINPR_ASSERT(buffer);
1154 WINPR_ASSERT(size > 0);
1156 if (!update_password(file, password))
1159 char* uploadinfo = NULL;
1160 size_t uploadinfosize = 0;
1161 if (freerdp_assistance_consume_input_and_get_element(buffer,
"UPLOADINFO", &uploadinfo,
1163 return freerdp_assistance_parse_uploadinfo(file, uploadinfo, uploadinfosize);
1166 const char* estr = freerdp_assistance_contains_element(buffer, size,
"E", &elen, NULL, NULL);
1167 if (!estr || (elen == 0))
1169 WLog_ERR(TAG,
"Failed to parse ASSISTANCE file: Neither UPLOADINFO nor <E> found");
1172 if (!update_connectionstring2(file, estr, elen))
1175 if (!freerdp_assistance_parse_connection_string2(file))
1181 int freerdp_assistance_parse_file_buffer(rdpAssistanceFile* file,
const char* cbuffer,
size_t size,
1182 const char* password)
1187 WLog_WARN(TAG,
"empty password supplied");
1190 if (!cbuffer || (size == 0))
1192 WLog_WARN(TAG,
"no data supplied [%p, %" PRIuz
"]", cbuffer, size);
1196 char* abuffer = strndup(cbuffer, size);
1197 const size_t len = strnlen(cbuffer, size);
1199 WLog_WARN(TAG,
"Input data not '\0' terminated");
1204 const int rc = freerdp_assistance_parse_file_buffer_int(file, abuffer, len + 1, password);
1209 int freerdp_assistance_parse_file(rdpAssistanceFile* file,
const char* name,
const char* password)
1212 BYTE* buffer = NULL;
1214 size_t readSize = 0;
1221 if (!update_name(file, name))
1224 fp = winpr_fopen(name,
"r");
1228 WLog_ERR(TAG,
"Failed to open ASSISTANCE file %s ", name);
1232 (void)_fseeki64(fp, 0, SEEK_END);
1233 fileSize.i64 = _ftelli64(fp);
1234 (void)_fseeki64(fp, 0, SEEK_SET);
1236 if (fileSize.i64 < 1)
1238 WLog_ERR(TAG,
"Failed to read ASSISTANCE file %s ", name);
1243 buffer = (BYTE*)malloc(fileSize.s + 2);
1251 readSize = fread(buffer, fileSize.s, 1, fp);
1256 readSize = fileSize.s;
1263 WLog_ERR(TAG,
"Failed to read ASSISTANCE file %s ", name);
1269 buffer[fileSize.s] =
'\0';
1270 buffer[fileSize.s + 1] =
'\0';
1271 status = freerdp_assistance_parse_file_buffer(file, (
char*)buffer, fileSize.s, password);
1276 BOOL freerdp_assistance_populate_settings_from_assistance_file(rdpAssistanceFile* file,
1277 rdpSettings* settings)
1282 if (!file->RASessionId || !file->MachineAddresses)
1298 file->ConnectionString2))
1309 if (ArrayList_Count(file->MachineAddresses) < 1)
1312 const char* addr = ArrayList_GetItem(file->MachineAddresses, 0);
1331 const size_t ports = ArrayList_Count(file->MachinePorts);
1332 const size_t addresses = ArrayList_Count(file->MachineAddresses);
1335 if (ports != addresses)
1343 cnv.data = ArrayList_GetItem(file->MachinePorts, 0);
1347 if (!freerdp_target_net_adresses_reset(settings, ports))
1350 for (
size_t x = 0; x < ports; x++)
1352 cnv.data = ArrayList_GetItem(file->MachinePorts, x);
1353 if (!freerdp_settings_set_pointer_array(settings, FreeRDP_TargetNetPorts, x, &cnv.port))
1356 for (
size_t i = 0; i < addresses; i++)
1358 const char* maddr = ArrayList_GetItem(file->MachineAddresses, i);
1359 if (!freerdp_settings_set_pointer_array(settings, FreeRDP_TargetNetAddresses, i, maddr))
1366 static BOOL setup_string(wArrayList* list)
1370 wObject* obj = ArrayList_Object(list);
1373 obj->fnObjectFree = free;
1378 rdpAssistanceFile* freerdp_assistance_file_new(
void)
1380 winpr_InitializeSSL(WINPR_SSL_INIT_DEFAULT);
1381 rdpAssistanceFile* file = calloc(1,
sizeof(rdpAssistanceFile));
1385 file->MachineAddresses = ArrayList_New(FALSE);
1386 file->MachinePorts = ArrayList_New(FALSE);
1387 file->MachineUris = ArrayList_New(FALSE);
1389 if (!file->MachineAddresses || !file->MachinePorts || !file->MachineUris)
1392 if (!setup_string(file->MachineAddresses) || !setup_string(file->MachineUris))
1398 WINPR_PRAGMA_DIAG_PUSH
1399 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
1400 freerdp_assistance_file_free(file);
1401 WINPR_PRAGMA_DIAG_POP
1405 void freerdp_assistance_file_free(rdpAssistanceFile* file)
1410 update_password(file, NULL);
1411 update_connectionstring2(file, NULL, 0);
1412 free(file->filename);
1413 free(file->Username);
1414 free(file->LHTicket);
1415 free(file->RCTicket);
1416 free(file->PassStub);
1417 free(file->ConnectionString1);
1418 free(file->EncryptedLHTicket);
1419 free(file->RASessionId);
1420 free(file->RASpecificParams);
1421 free(file->RASpecificParams2);
1422 free(file->EncryptedPassStub);
1424 ArrayList_Free(file->MachineAddresses);
1425 ArrayList_Free(file->MachinePorts);
1426 ArrayList_Free(file->MachineUris);
1430 void freerdp_assistance_print_file(rdpAssistanceFile* file, wLog* log, DWORD level)
1434 WLog_Print(log, level,
"Username: %s", file->Username);
1435 WLog_Print(log, level,
"LHTicket: %s", file->LHTicket);
1436 WLog_Print(log, level,
"RCTicket: %s", file->RCTicket);
1437 WLog_Print(log, level,
"RCTicketEncrypted: %" PRId32, file->RCTicketEncrypted);
1438 WLog_Print(log, level,
"PassStub: %s", file->PassStub);
1439 WLog_Print(log, level,
"DtStart: %" PRIu32, file->DtStart);
1440 WLog_Print(log, level,
"DtLength: %" PRIu32, file->DtLength);
1441 WLog_Print(log, level,
"LowSpeed: %" PRId32, file->LowSpeed);
1442 WLog_Print(log, level,
"RASessionId: %s", file->RASessionId);
1443 WLog_Print(log, level,
"RASpecificParams: %s", file->RASpecificParams);
1444 WLog_Print(log, level,
"RASpecificParams2: %s", file->RASpecificParams2);
1446 for (
size_t x = 0; x < ArrayList_Count(file->MachineAddresses); x++)
1449 const char* uri = NULL;
1450 const char* addr = ArrayList_GetItem(file->MachineAddresses, x);
1451 if (x < ArrayList_Count(file->MachinePorts))
1458 cnv.data = ArrayList_GetItem(file->MachinePorts, x);
1461 if (x < ArrayList_Count(file->MachineUris))
1462 uri = ArrayList_GetItem(file->MachineUris, x);
1464 WLog_Print(log, level,
"MachineAddress [%" PRIdz
": %s", x, addr);
1465 WLog_Print(log, level,
"MachinePort [%" PRIdz
": %" PRIu32, x, port);
1466 WLog_Print(log, level,
"MachineURI [%" PRIdz
": %s", x, uri);
1470 BOOL freerdp_assistance_get_encrypted_pass_stub(rdpAssistanceFile* file,
const char** pwd,
1473 if (!file || !pwd || !size)
1476 *pwd = (
const char*)file->EncryptedPassStub;
1477 *size = file->EncryptedPassStubLength;
1481 int freerdp_assistance_set_connection_string2(rdpAssistanceFile* file,
const char*
string,
1482 const char* password)
1484 if (!file || !
string || !password)
1487 char* str = _strdup(
string);
1491 if (!update_connectionstring2_nocopy(file, str))
1493 if (!update_password(file, password))
1495 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.