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
"]",
1203 WINPR_CXX_COMPAT_CAST(
const void*, cbuffer), size);
1207 char* abuffer = strndup(cbuffer, size);
1208 const size_t len = strnlen(cbuffer, size);
1210 WLog_WARN(TAG,
"Input data not '\\0' terminated");
1215 const int rc = freerdp_assistance_parse_file_buffer_int(file, abuffer, len + 1, password);
1220int freerdp_assistance_parse_file(rdpAssistanceFile* file,
const char* name,
const char* password)
1223 BYTE* buffer = NULL;
1225 size_t readSize = 0;
1232 if (!update_name(file, name))
1235 fp = winpr_fopen(name,
"r");
1239 WLog_ERR(TAG,
"Failed to open ASSISTANCE file %s ", name);
1243 (void)_fseeki64(fp, 0, SEEK_END);
1244 fileSize.i64 = _ftelli64(fp);
1245 (void)_fseeki64(fp, 0, SEEK_SET);
1247 if (fileSize.i64 < 1)
1249 WLog_ERR(TAG,
"Failed to read ASSISTANCE file %s ", name);
1254 buffer = (BYTE*)malloc(fileSize.s + 2);
1262 readSize = fread(buffer, fileSize.s, 1, fp);
1267 readSize = fileSize.s;
1274 WLog_ERR(TAG,
"Failed to read ASSISTANCE file %s ", name);
1280 buffer[fileSize.s] =
'\0';
1281 buffer[fileSize.s + 1] =
'\0';
1282 status = freerdp_assistance_parse_file_buffer(file, (
char*)buffer, fileSize.s, password);
1287BOOL freerdp_assistance_populate_settings_from_assistance_file(rdpAssistanceFile* file,
1288 rdpSettings* settings)
1293 if (!file->RASessionId || !file->MachineAddresses)
1309 file->ConnectionString2))
1320 if (ArrayList_Count(file->MachineAddresses) < 1)
1323 const char* addr = ArrayList_GetItem(file->MachineAddresses, 0);
1342 const size_t ports = ArrayList_Count(file->MachinePorts);
1343 const size_t addresses = ArrayList_Count(file->MachineAddresses);
1346 if (ports != addresses)
1354 cnv.data = ArrayList_GetItem(file->MachinePorts, 0);
1355 WINPR_ASSERT(cnv.port <= UINT32_MAX);
1359 if (!freerdp_target_net_adresses_reset(settings, ports))
1362 for (
size_t x = 0; x < ports; x++)
1364 cnv.data = ArrayList_GetItem(file->MachinePorts, x);
1365 WINPR_ASSERT(cnv.port <= UINT32_MAX);
1366 const UINT32 port = (UINT32)cnv.port;
1367 if (!freerdp_settings_set_pointer_array(settings, FreeRDP_TargetNetPorts, x, &port))
1370 for (
size_t i = 0; i < addresses; i++)
1372 const char* maddr = ArrayList_GetItem(file->MachineAddresses, i);
1373 if (!freerdp_settings_set_pointer_array(settings, FreeRDP_TargetNetAddresses, i, maddr))
1380static BOOL setup_string(wArrayList* list)
1384 wObject* obj = ArrayList_Object(list);
1387 obj->fnObjectFree = free;
1392rdpAssistanceFile* freerdp_assistance_file_new(
void)
1394 winpr_InitializeSSL(WINPR_SSL_INIT_DEFAULT);
1395 rdpAssistanceFile* file = calloc(1,
sizeof(rdpAssistanceFile));
1399 file->MachineAddresses = ArrayList_New(FALSE);
1400 file->MachinePorts = ArrayList_New(FALSE);
1401 file->MachineUris = ArrayList_New(FALSE);
1403 if (!file->MachineAddresses || !file->MachinePorts || !file->MachineUris)
1406 if (!setup_string(file->MachineAddresses) || !setup_string(file->MachineUris))
1412 WINPR_PRAGMA_DIAG_PUSH
1413 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
1414 freerdp_assistance_file_free(file);
1415 WINPR_PRAGMA_DIAG_POP
1419void freerdp_assistance_file_free(rdpAssistanceFile* file)
1424 update_password(file, NULL);
1425 update_connectionstring2(file, NULL, 0);
1426 free(file->filename);
1427 free(file->Username);
1428 free(file->LHTicket);
1429 free(file->RCTicket);
1430 free(file->PassStub);
1431 free(file->ConnectionString1);
1432 free(file->EncryptedLHTicket);
1433 free(file->RASessionId);
1434 free(file->RASpecificParams);
1435 free(file->RASpecificParams2);
1436 free(file->EncryptedPassStub);
1438 ArrayList_Free(file->MachineAddresses);
1439 ArrayList_Free(file->MachinePorts);
1440 ArrayList_Free(file->MachineUris);
1444void freerdp_assistance_print_file(rdpAssistanceFile* file, wLog* log, DWORD level)
1448 WLog_Print(log, level,
"Username: %s", file->Username);
1449 WLog_Print(log, level,
"LHTicket: %s", file->LHTicket);
1450 WLog_Print(log, level,
"RCTicket: %s", file->RCTicket);
1451 WLog_Print(log, level,
"RCTicketEncrypted: %" PRId32, file->RCTicketEncrypted);
1452 WLog_Print(log, level,
"PassStub: %s", file->PassStub);
1453 WLog_Print(log, level,
"DtStart: %" PRIu32, file->DtStart);
1454 WLog_Print(log, level,
"DtLength: %" PRIu32, file->DtLength);
1455 WLog_Print(log, level,
"LowSpeed: %" PRId32, file->LowSpeed);
1456 WLog_Print(log, level,
"RASessionId: %s", file->RASessionId);
1457 WLog_Print(log, level,
"RASpecificParams: %s", file->RASpecificParams);
1458 WLog_Print(log, level,
"RASpecificParams2: %s", file->RASpecificParams2);
1460 for (
size_t x = 0; x < ArrayList_Count(file->MachineAddresses); x++)
1463 const char* uri = NULL;
1464 const char* addr = ArrayList_GetItem(file->MachineAddresses, x);
1465 if (x < ArrayList_Count(file->MachinePorts))
1472 cnv.data = ArrayList_GetItem(file->MachinePorts, x);
1473 WINPR_ASSERT(cnv.port <= UINT32_MAX);
1474 port = (UINT32)cnv.port;
1476 if (x < ArrayList_Count(file->MachineUris))
1477 uri = ArrayList_GetItem(file->MachineUris, x);
1479 WLog_Print(log, level,
"MachineAddress [%" PRIuz
": %s", x, addr);
1480 WLog_Print(log, level,
"MachinePort [%" PRIuz
": %" PRIu32, x, port);
1481 WLog_Print(log, level,
"MachineURI [%" PRIuz
": %s", x, uri);
1485BOOL freerdp_assistance_get_encrypted_pass_stub(rdpAssistanceFile* file,
const char** pwd,
1488 if (!file || !pwd || !size)
1491 *pwd = (
const char*)file->EncryptedPassStub;
1492 *size = file->EncryptedPassStubLength;
1496int freerdp_assistance_set_connection_string2(rdpAssistanceFile* file,
const char*
string,
1497 const char* password)
1499 if (!file || !
string || !password)
1502 char* str = _strdup(
string);
1506 if (!update_connectionstring2_nocopy(file, str))
1508 if (!update_password(file, password))
1510 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.