22#include <freerdp/config.h>
27#include <winpr/string.h>
28#include <freerdp/log.h>
29#include <freerdp/crypto/certificate.h>
30#include <freerdp/redirection.h>
31#include <freerdp/utils/string.h>
33#include "../crypto/certificate.h"
34#include "redirection.h"
37#define TAG FREERDP_TAG("core.redirection")
48 UINT32 PasswordLength;
50 BYTE* LoadBalanceInfo;
51 UINT32 LoadBalanceInfoLength;
52 char* TargetNetBiosName;
53 char* TargetNetAddress;
54 UINT32 TargetNetAddressesCount;
55 char** TargetNetAddresses;
56 UINT32 RedirectionGuidLength;
57 BYTE* RedirectionGuid;
59 rdpCertificate* TargetCertificate;
62static void redirection_free_array(
char*** what, UINT32* count)
69 for (UINT32 x = 0; x < *count; x++)
78static void redirection_free_string(
char** str)
85static void redirection_free_data(BYTE** str, UINT32* length)
94static BOOL redirection_copy_string(
char** dst,
const char* str)
96 redirection_free_string(dst);
104static BOOL redirection_copy_data(BYTE** dst, UINT32* plen,
const BYTE* str,
size_t len)
106 redirection_free_data(dst, plen);
108 if (!str || (len == 0))
110 if (len > UINT32_MAX)
116 memcpy(*dst, str, len);
121static BOOL redirection_copy_array(
char*** dst, UINT32* plen,
const char** str,
size_t len)
123 redirection_free_array(dst, plen);
125 if (len > UINT32_MAX)
127 if (!str || (len == 0))
130 *dst = (
char**)calloc(len,
sizeof(
char*));
135 for (
size_t x = 0; x < len; x++)
138 (*dst)[x] = _strdup(str[x]);
142 redirection_free_array(dst, plen);
150static BOOL rdp_redirection_get_data(
wStream* s, UINT32* pLength,
const BYTE** pData)
152 WINPR_ASSERT(pLength);
155 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
158 Stream_Read_UINT32(s, *pLength);
160 if (!Stream_CheckAndLogRequiredLength(TAG, s, *pLength))
163 *pData = Stream_ConstPointer(s);
164 Stream_Seek(s, *pLength);
168static BOOL rdp_redirection_read_unicode_string(
wStream* s,
char** str,
size_t maxLength)
171 const BYTE* data = NULL;
173 if (!rdp_redirection_get_data(s, &length, &data))
176 const WCHAR* wstr = (
const WCHAR*)data;
178 if ((length % 2) || length < 2 || length > maxLength)
180 WLog_ERR(TAG,
"failure: invalid unicode string length: %" PRIu32
"", length);
184 if (wstr[length / 2 - 1])
186 WLog_ERR(TAG,
"failure: unterminated unicode string");
190 redirection_free_string(str);
191 *str = ConvertWCharNToUtf8Alloc(wstr, length /
sizeof(WCHAR), NULL);
194 WLog_ERR(TAG,
"failure: string conversion failed");
201static BOOL rdp_redirection_write_data(
wStream* s,
size_t length,
const void* data)
203 WINPR_ASSERT(data || (length == 0));
204 WINPR_ASSERT(length <= UINT32_MAX);
206 if (!Stream_EnsureRemainingCapacity(s, 4))
209 Stream_Write_UINT32(s, (UINT32)length);
211 if (!Stream_EnsureRemainingCapacity(s, length))
214 Stream_Write(s, data, length);
218static BOOL rdp_redirection_write_base64_wchar(WINPR_ATTR_UNUSED UINT32 flag,
wStream* s,
219 size_t length,
const void* data)
223 char* base64 = crypto_base64_encode(data, length);
227 size_t wbase64len = 0;
228 WCHAR* wbase64 = ConvertUtf8ToWCharAlloc(base64, &wbase64len);
233 rc = rdp_redirection_write_data(s, wbase64len *
sizeof(WCHAR), wbase64);
238static BOOL rdp_redirection_read_base64_wchar(UINT32 flag,
wStream* s, UINT32* pLength,
242 char buffer[64] = { 0 };
243 const BYTE* ptr = NULL;
245 if (!rdp_redirection_get_data(s, pLength, &ptr))
247 const WCHAR* wchar = (
const WCHAR*)ptr;
250 char* utf8 = ConvertWCharNToUtf8Alloc(wchar, *pLength /
sizeof(WCHAR), &utf8_len);
254 redirection_free_data(pData, NULL);
256 utf8_len = strnlen(utf8, utf8_len);
259 *pData = calloc(utf8_len,
sizeof(BYTE));
264 size_t rlen = utf8_len;
266 char* saveptr = NULL;
267 char* tok = strtok_s(utf8,
"\r\n", &saveptr);
270 const size_t len = strnlen(tok, rlen);
275 crypto_base64_decode(tok, len, &bptr, &bplen);
278 memcpy(&(*pData)[wpos], bptr, bplen);
282 tok = strtok_s(NULL,
"\r\n", &saveptr);
284 if (wpos > UINT32_MAX)
287 *pLength = (UINT32)wpos;
289 WLog_DBG(TAG,
"%s:", rdp_redirection_flags_to_string(flag, buffer,
sizeof(buffer)));
295 WLog_ERR(TAG,
"failed to read base64 data");
300static BOOL rdp_target_cert_get_element(
wStream* s, UINT32* pType, UINT32* pEncoding,
301 const BYTE** ptr,
size_t* pLength)
304 WINPR_ASSERT(pEncoding);
306 WINPR_ASSERT(pLength);
308 if (!Stream_CheckAndLogRequiredLength(TAG, s, 12))
313 UINT32 elementSize = 0;
315 Stream_Read_UINT32(s, type);
316 Stream_Read_UINT32(s, encoding);
317 Stream_Read_UINT32(s, elementSize);
319 if (!Stream_CheckAndLogRequiredLength(TAG, s, elementSize))
322 *ptr = Stream_ConstPointer(s);
323 *pLength = elementSize;
324 Stream_Seek(s, elementSize);
327 *pEncoding = encoding;
331static BOOL rdp_target_cert_write_element(
wStream* s, UINT32 Type, UINT32 Encoding,
332 const BYTE* data,
size_t length)
334 WINPR_ASSERT(data || (length == 0));
335 WINPR_ASSERT(length <= UINT32_MAX);
337 if (!Stream_EnsureRemainingCapacity(s, 12))
340 Stream_Write_UINT32(s, Type);
341 Stream_Write_UINT32(s, Encoding);
342 Stream_Write_UINT32(s, (UINT32)length);
344 if (!Stream_EnsureRemainingCapacity(s, length))
347 Stream_Write(s, data, length);
351BOOL rdp_redirection_read_target_cert(rdpCertificate** ptargetCertificate,
const BYTE* data,
354 WINPR_ASSERT(ptargetCertificate);
357 wStream* s = Stream_StaticConstInit(&sbuffer, data, length);
359 freerdp_certificate_free(*ptargetCertificate);
360 *ptargetCertificate = NULL;
363 const BYTE* ptr = NULL;
364 while (Stream_GetRemainingLength(s) > 0)
368 if (!rdp_target_cert_get_element(s, &type, &encoding, &ptr, &plength))
373 case CERT_cert_file_element:
374 if (encoding == ENCODING_TYPE_ASN1_DER)
376 if (*ptargetCertificate)
377 WLog_WARN(TAG,
"Duplicate TargetCertificate in data detected!");
380 *ptargetCertificate = freerdp_certificate_new_from_der(ptr, plength);
381 if (!*ptargetCertificate)
382 WLog_ERR(TAG,
"TargetCertificate parsing DER data failed");
388 "TargetCertificate data in unknown encoding %" PRIu32
" detected!",
394 "Unknown TargetCertificate field type %" PRIu32
", encoding %" PRIu32
395 " of length %" PRIuz,
396 type, encoding, plength);
401 return *ptargetCertificate != NULL;
404static BOOL rdp_redirection_write_target_cert(
wStream* s,
const rdpRedirection* redirection)
407 WINPR_ASSERT(redirection);
409 const rdpCertificate* cert = redirection->TargetCertificate;
415 BYTE* der = freerdp_certificate_get_der(cert, &derlen);
416 if (!rdp_target_cert_write_element(s, CERT_cert_file_element, ENCODING_TYPE_ASN1_DER, der,
427static BOOL rdp_redireciton_write_target_cert_stream(
wStream* s,
const rdpRedirection* redirection)
430 wStream* serialized = Stream_New(NULL, 2048);
434 if (!rdp_redirection_write_target_cert(serialized, redirection))
437 rc = rdp_redirection_write_base64_wchar(
438 LB_TARGET_CERTIFICATE, s, Stream_GetPosition(serialized), Stream_Buffer(serialized));
441 Stream_Free(serialized, TRUE);
445static BOOL rdp_redirection_read_target_cert_stream(
wStream* s, rdpRedirection* redirection)
450 WINPR_ASSERT(redirection);
453 if (rdp_redirection_read_base64_wchar(LB_TARGET_CERTIFICATE, s, &length, &ptr))
454 rc = rdp_redirection_read_target_cert(&redirection->TargetCertificate, ptr, length);
459BOOL rdp_set_target_certificate(rdpSettings* settings,
const rdpCertificate* tcert)
461 rdpCertificate* cert = freerdp_certificate_clone(tcert);
467 char* pem = freerdp_certificate_get_pem(cert, &length);
468 if (pem && (length <= UINT32_MAX))
480int rdp_redirection_apply_settings(rdpRdp* rdp)
482 rdpSettings* settings = NULL;
483 rdpRedirection* redirection = NULL;
485 if (!rdp_reset_runtime_settings(rdp))
488 settings = rdp->settings;
489 WINPR_ASSERT(settings);
491 redirection = rdp->redirection;
492 WINPR_ASSERT(redirection);
494 settings->RedirectionFlags = redirection->flags;
495 settings->RedirectedSessionId = redirection->sessionID;
497 if (settings->RedirectionFlags & LB_TARGET_NET_ADDRESS)
500 redirection->TargetNetAddress))
504 if (settings->RedirectionFlags & LB_USERNAME)
507 redirection->Username))
511 if (settings->RedirectionFlags & LB_DOMAIN)
517 if (settings->RedirectionFlags & LB_PASSWORD)
521 redirection->Password, redirection->PasswordLength))
525 if (settings->RedirectionFlags & LB_DONTSTOREUSERNAME)
530 if (settings->RedirectionFlags & LB_SMARTCARD_LOGON)
535 if (settings->RedirectionFlags & LB_NOREDIRECT)
540 if (settings->RedirectionFlags & LB_TARGET_FQDN)
543 redirection->TargetFQDN))
547 if (settings->RedirectionFlags & LB_TARGET_NETBIOS_NAME)
550 redirection->TargetNetBiosName))
554 if (settings->RedirectionFlags & LB_TARGET_NET_ADDRESSES)
556 if (!freerdp_target_net_addresses_copy(settings, redirection->TargetNetAddresses,
557 redirection->TargetNetAddressesCount))
561 if (settings->RedirectionFlags & LB_CLIENT_TSV_URL)
565 redirection->TsvUrl, redirection->TsvUrlLength))
576 ConvertWCharNToUtf8Alloc((
const WCHAR*)redirection->TsvUrl,
577 redirection->TsvUrlLength /
sizeof(WCHAR), &tsvlen);
580 else if (tsvlen != lblen)
582 else if (memcmp(tsv, lb, lblen) != 0)
588 "[redirection] Expected TsvUrl '%s' [%" PRIuz
"], but got '%s' [%" PRIuz
590 lb, lblen, tsv, tsvlen);
599 if (settings->RedirectionFlags & LB_SERVER_TSV_CAPABLE)
604 if (settings->RedirectionFlags & LB_LOAD_BALANCE_INFO)
608 redirection->LoadBalanceInfo,
609 redirection->LoadBalanceInfoLength))
622 if (settings->RedirectionFlags & LB_PASSWORD_IS_PK_ENCRYPTED)
627 if (settings->RedirectionFlags & LB_REDIRECTION_GUID)
630 redirection->RedirectionGuid,
631 redirection->RedirectionGuidLength))
635 if (settings->RedirectionFlags & LB_TARGET_CERTIFICATE)
637 if (!rdp_set_target_certificate(settings, redirection->TargetCertificate))
644static BOOL rdp_redirection_read_data(UINT32 flag,
wStream* s, UINT32* pLength, BYTE** pData)
646 char buffer[64] = { 0 };
647 const BYTE* ptr = NULL;
649 if (!rdp_redirection_get_data(s, pLength, &ptr))
652 redirection_free_data(pData, NULL);
653 *pData = (BYTE*)malloc(*pLength);
657 memcpy(*pData, ptr, *pLength);
659 WLog_DBG(TAG,
"%s:", rdp_redirection_flags_to_string(flag, buffer,
sizeof(buffer)));
664static state_run_t rdp_recv_server_redirection_pdu(rdpRdp* rdp,
wStream* s)
666 char buffer[256] = { 0 };
669 rdpRedirection* redirection = rdp->redirection;
671 if (!Stream_CheckAndLogRequiredLength(TAG, s, 12))
672 return STATE_RUN_FAILED;
674 Stream_Read_UINT16(s, flags);
675 if (flags != SEC_REDIRECTION_PKT)
677 char buffer1[1024] = { 0 };
678 char buffer2[1024] = { 0 };
679 WLog_ERR(TAG,
"received invalid flags=%s, expected %s",
680 rdp_security_flag_string(flags, buffer1,
sizeof(buffer1)),
681 rdp_security_flag_string(SEC_REDIRECTION_PKT, buffer2,
sizeof(buffer2)));
682 return STATE_RUN_FAILED;
684 Stream_Read_UINT16(s, length);
685 Stream_Read_UINT32(s, redirection->sessionID);
686 Stream_Read_UINT32(s, redirection->flags);
688 "flags: 0x%04" PRIX16
", length: %" PRIu16
", sessionID: 0x%08" PRIX32
689 ", redirFlags: %s [0x%08" PRIX32
"]",
690 flags, length, redirection->sessionID,
691 rdp_redirection_flags_to_string(redirection->flags, buffer,
sizeof(buffer)),
706 if (redirection->flags & LB_TARGET_NET_ADDRESS)
708 if (!rdp_redirection_read_unicode_string(s, &(redirection->TargetNetAddress), 80))
709 return STATE_RUN_FAILED;
712 if (redirection->flags & LB_LOAD_BALANCE_INFO)
720 if (!rdp_redirection_read_data(LB_LOAD_BALANCE_INFO, s, &redirection->LoadBalanceInfoLength,
721 &redirection->LoadBalanceInfo))
722 return STATE_RUN_FAILED;
725 if (redirection->flags & LB_USERNAME)
727 if (!rdp_redirection_read_unicode_string(s, &(redirection->Username), 512))
728 return STATE_RUN_FAILED;
730 WLog_DBG(TAG,
"Username: %s", redirection->Username);
733 if (redirection->flags & LB_DOMAIN)
735 if (!rdp_redirection_read_unicode_string(s, &(redirection->Domain), 52))
736 return STATE_RUN_FAILED;
738 WLog_DBG(TAG,
"Domain: %s", redirection->Domain);
741 if (redirection->flags & LB_PASSWORD)
764 if (!rdp_redirection_read_data(LB_PASSWORD, s, &redirection->PasswordLength,
765 &redirection->Password))
766 return STATE_RUN_FAILED;
772 if ((redirection->flags & LB_PASSWORD_IS_PK_ENCRYPTED) == 0)
774 const size_t charLen = redirection->PasswordLength /
sizeof(WCHAR);
775 if (redirection->PasswordLength > LB_PASSWORD_MAX_LENGTH)
777 WLog_ERR(TAG,
"LB_PASSWORD: %" PRIuz
" exceeds limit of %d", charLen,
778 LB_PASSWORD_MAX_LENGTH);
779 return STATE_RUN_FAILED;
783 if (_wcsnlen((
const WCHAR*)redirection->Password, charLen) == charLen)
785 WLog_ERR(TAG,
"LB_PASSWORD: missing '\\0' termination");
786 return STATE_RUN_FAILED;
791 if (redirection->flags & LB_TARGET_FQDN)
793 if (!rdp_redirection_read_unicode_string(s, &(redirection->TargetFQDN), 512))
794 return STATE_RUN_FAILED;
796 WLog_DBG(TAG,
"TargetFQDN: %s", redirection->TargetFQDN);
799 if (redirection->flags & LB_TARGET_NETBIOS_NAME)
801 if (!rdp_redirection_read_unicode_string(s, &(redirection->TargetNetBiosName), 32))
802 return STATE_RUN_FAILED;
804 WLog_DBG(TAG,
"TargetNetBiosName: %s", redirection->TargetNetBiosName);
807 if (redirection->flags & LB_CLIENT_TSV_URL)
809 if (!rdp_redirection_read_data(LB_CLIENT_TSV_URL, s, &redirection->TsvUrlLength,
810 &redirection->TsvUrl))
811 return STATE_RUN_FAILED;
814 if (redirection->flags & LB_REDIRECTION_GUID)
816 if (!rdp_redirection_read_data(LB_REDIRECTION_GUID, s, &redirection->RedirectionGuidLength,
817 &redirection->RedirectionGuid))
818 return STATE_RUN_FAILED;
821 if (redirection->flags & LB_TARGET_CERTIFICATE)
823 if (!rdp_redirection_read_target_cert_stream(s, redirection))
824 return STATE_RUN_FAILED;
827 if (redirection->flags & LB_TARGET_NET_ADDRESSES)
829 UINT32 targetNetAddressesLength = 0;
830 UINT32 TargetNetAddressesCount = 0;
832 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
833 return STATE_RUN_FAILED;
835 Stream_Read_UINT32(s, targetNetAddressesLength);
836 Stream_Read_UINT32(s, TargetNetAddressesCount);
841 const size_t size = TargetNetAddressesCount *
sizeof(WCHAR);
842 if ((size > Stream_GetRemainingLength(s)) || (size > targetNetAddressesLength))
845 "Invalid RDP_SERVER_REDIRECTION_PACKET::TargetNetAddressLength %" PRIuz
846 ", sanity limit is %" PRIuz,
847 TargetNetAddressesCount *
sizeof(WCHAR), Stream_GetRemainingLength(s));
848 return STATE_RUN_FAILED;
851 redirection_free_array(&redirection->TargetNetAddresses,
852 &redirection->TargetNetAddressesCount);
853 if (TargetNetAddressesCount > 0)
855 redirection->TargetNetAddresses =
856 (
char**)calloc(TargetNetAddressesCount,
sizeof(
char*));
858 if (!redirection->TargetNetAddresses)
860 WLog_ERR(TAG,
"TargetNetAddresses %" PRIu32
" failed to allocate",
861 TargetNetAddressesCount);
862 return STATE_RUN_FAILED;
865 redirection->TargetNetAddressesCount = TargetNetAddressesCount;
867 WLog_DBG(TAG,
"TargetNetAddressesCount: %" PRIu32
"", TargetNetAddressesCount);
869 for (UINT32 i = 0; i < TargetNetAddressesCount; i++)
871 if (!rdp_redirection_read_unicode_string(s, &(redirection->TargetNetAddresses[i]), 80))
872 return STATE_RUN_FAILED;
874 WLog_DBG(TAG,
"TargetNetAddresses[%" PRIu32
"]: %s", i,
875 redirection->TargetNetAddresses[i]);
879 if (Stream_GetRemainingLength(s) >= 8)
885 if (redirection->flags & LB_NOREDIRECT)
886 return STATE_RUN_SUCCESS;
888 return STATE_RUN_REDIRECT;
891state_run_t rdp_recv_enhanced_security_redirection_packet(rdpRdp* rdp,
wStream* s)
893 state_run_t status = STATE_RUN_SUCCESS;
895 if (!Stream_SafeSeek(s, 2))
896 return STATE_RUN_FAILED;
898 status = rdp_recv_server_redirection_pdu(rdp, s);
900 if (state_run_failed(status))
903 if (Stream_GetRemainingLength(s) >= 1)
912rdpRedirection* redirection_new(
void)
914 rdpRedirection* redirection = (rdpRedirection*)calloc(1,
sizeof(rdpRedirection));
923void redirection_free(rdpRedirection* redirection)
927 redirection_free_data(&redirection->TsvUrl, &redirection->TsvUrlLength);
928 redirection_free_string(&redirection->Username);
929 redirection_free_string(&redirection->Domain);
930 redirection_free_string(&redirection->TargetFQDN);
931 redirection_free_string(&redirection->TargetNetBiosName);
932 redirection_free_string(&redirection->TargetNetAddress);
933 redirection_free_data(&redirection->LoadBalanceInfo, &redirection->LoadBalanceInfoLength);
934 redirection_free_data(&redirection->Password, &redirection->PasswordLength);
935 redirection_free_data(&redirection->RedirectionGuid, &redirection->RedirectionGuidLength);
936 freerdp_certificate_free(redirection->TargetCertificate);
937 redirection_free_array(&redirection->TargetNetAddresses,
938 &redirection->TargetNetAddressesCount);
944static SSIZE_T redir_write_string(WINPR_ATTR_UNUSED UINT32 flag,
wStream* s,
const char* str)
946 const size_t length = (strlen(str) + 1);
947 if (!Stream_EnsureRemainingCapacity(s, 4ull + length *
sizeof(WCHAR)))
950 const size_t pos = Stream_GetPosition(s);
951 Stream_Write_UINT32(s, (UINT32)length *
sizeof(WCHAR));
952 if (Stream_Write_UTF16_String_From_UTF8(s, length, str, length, TRUE) < 0)
954 return (SSIZE_T)(Stream_GetPosition(s) - pos);
957static BOOL redir_write_data(WINPR_ATTR_UNUSED UINT32 flag,
wStream* s, UINT32 length,
960 if (!Stream_EnsureRemainingCapacity(s, 4ull + length))
963 Stream_Write_UINT32(s, length);
964 Stream_Write(s, data, length);
968BOOL rdp_write_enhanced_security_redirection_packet(
wStream* s,
const rdpRedirection* redirection)
973 WINPR_ASSERT(redirection);
975 if (!Stream_EnsureRemainingCapacity(s, 14))
978 Stream_Write_UINT16(s, 0);
981 const size_t start = Stream_GetPosition(s);
982 Stream_Write_UINT16(s, SEC_REDIRECTION_PKT);
983 const size_t lengthOffset = Stream_GetPosition(s);
984 Stream_Seek_UINT16(s);
986 if (redirection->sessionID)
987 Stream_Write_UINT32(s, redirection->sessionID);
989 Stream_Write_UINT32(s, 0);
991 Stream_Write_UINT32(s, redirection->flags);
993 if (redirection->flags & LB_TARGET_NET_ADDRESS)
995 if (redir_write_string(LB_TARGET_NET_ADDRESS, s, redirection->TargetNetAddress) < 0)
999 if (redirection->flags & LB_LOAD_BALANCE_INFO)
1001 const UINT32 length = 13 + redirection->LoadBalanceInfoLength + 2;
1002 if (!Stream_EnsureRemainingCapacity(s, length))
1004 Stream_Write_UINT32(s, length);
1005 Stream_Write(s,
"Cookie: msts=", 13);
1006 Stream_Write(s, redirection->LoadBalanceInfo, redirection->LoadBalanceInfoLength);
1007 Stream_Write_UINT8(s, 0x0d);
1008 Stream_Write_UINT8(s, 0x0a);
1011 if (redirection->flags & LB_USERNAME)
1013 if (redir_write_string(LB_USERNAME, s, redirection->Username) < 0)
1017 if (redirection->flags & LB_DOMAIN)
1019 if (redir_write_string(LB_DOMAIN, s, redirection->Domain) < 0)
1023 if (redirection->flags & LB_PASSWORD)
1026 if (!redir_write_data(LB_PASSWORD, s, redirection->PasswordLength,
1027 redirection->Password))
1031 if (redirection->flags & LB_TARGET_FQDN)
1033 if (redir_write_string(LB_TARGET_FQDN, s, redirection->TargetFQDN) < 0)
1037 if (redirection->flags & LB_TARGET_NETBIOS_NAME)
1039 if (redir_write_string(LB_TARGET_NETBIOS_NAME, s, redirection->TargetNetBiosName) < 0)
1043 if (redirection->flags & LB_CLIENT_TSV_URL)
1045 if (!redir_write_data(LB_CLIENT_TSV_URL, s, redirection->TsvUrlLength,
1046 redirection->TsvUrl))
1050 if (redirection->flags & LB_REDIRECTION_GUID)
1052 if (!redir_write_data(LB_REDIRECTION_GUID, s, redirection->RedirectionGuidLength,
1053 redirection->RedirectionGuid))
1057 if (redirection->flags & LB_TARGET_CERTIFICATE)
1059 if (!rdp_redireciton_write_target_cert_stream(s, redirection))
1063 if (redirection->flags & LB_TARGET_NET_ADDRESSES)
1065 UINT32 length =
sizeof(UINT32);
1067 if (!Stream_EnsureRemainingCapacity(s, 2 *
sizeof(UINT32)))
1070 const size_t lstart = Stream_GetPosition(s);
1071 Stream_Seek_UINT32(s);
1072 Stream_Write_UINT32(s, redirection->TargetNetAddressesCount);
1073 for (UINT32 i = 0; i < redirection->TargetNetAddressesCount; i++)
1075 const SSIZE_T rcc = redir_write_string(LB_TARGET_NET_ADDRESSES, s,
1076 redirection->TargetNetAddresses[i]);
1079 length += (UINT32)rcc;
1083 const size_t lend = Stream_GetPosition(s);
1084 Stream_SetPosition(s, lstart);
1085 Stream_Write_UINT32(s, length);
1086 Stream_SetPosition(s, lend);
1090 if (!Stream_EnsureRemainingCapacity(s, 8))
1095 const size_t end = Stream_GetPosition(s);
1096 Stream_SetPosition(s, lengthOffset);
1097 Stream_Write_UINT16(s, (UINT16)(end - start));
1098 Stream_SetPosition(s, end);
1107BOOL redirection_settings_are_valid(rdpRedirection* redirection, UINT32* pFlags)
1111 WINPR_ASSERT(redirection);
1113 if (redirection->flags & LB_CLIENT_TSV_URL)
1115 if (!redirection->TsvUrl || (redirection->TsvUrlLength == 0))
1116 flags |= LB_CLIENT_TSV_URL;
1119 if (redirection->flags & LB_SERVER_TSV_CAPABLE)
1121 if ((redirection->flags & LB_CLIENT_TSV_URL) == 0)
1122 flags |= LB_SERVER_TSV_CAPABLE;
1125 if (redirection->flags & LB_USERNAME)
1127 if (utils_str_is_empty(redirection->Username))
1128 flags |= LB_USERNAME;
1131 if (redirection->flags & LB_DOMAIN)
1133 if (utils_str_is_empty(redirection->Domain))
1137 if (redirection->flags & LB_PASSWORD)
1139 if (!redirection->Password || (redirection->PasswordLength == 0))
1140 flags |= LB_PASSWORD;
1143 if (redirection->flags & LB_TARGET_FQDN)
1145 if (utils_str_is_empty(redirection->TargetFQDN))
1146 flags |= LB_TARGET_FQDN;
1149 if (redirection->flags & LB_LOAD_BALANCE_INFO)
1151 if (!redirection->LoadBalanceInfo || (redirection->LoadBalanceInfoLength == 0))
1152 flags |= LB_LOAD_BALANCE_INFO;
1155 if (redirection->flags & LB_TARGET_NETBIOS_NAME)
1157 if (utils_str_is_empty(redirection->TargetNetBiosName))
1158 flags |= LB_TARGET_NETBIOS_NAME;
1161 if (redirection->flags & LB_TARGET_NET_ADDRESS)
1163 if (utils_str_is_empty(redirection->TargetNetAddress))
1164 flags |= LB_TARGET_NET_ADDRESS;
1167 if (redirection->flags & LB_TARGET_NET_ADDRESSES)
1169 if (!redirection->TargetNetAddresses || (redirection->TargetNetAddressesCount == 0))
1170 flags |= LB_TARGET_NET_ADDRESSES;
1173 for (UINT32 x = 0; x < redirection->TargetNetAddressesCount; x++)
1175 if (!redirection->TargetNetAddresses[x])
1176 flags |= LB_TARGET_NET_ADDRESSES;
1181 if (redirection->flags & LB_REDIRECTION_GUID)
1183 if (!redirection->RedirectionGuid || (redirection->RedirectionGuidLength == 0))
1184 flags |= LB_REDIRECTION_GUID;
1187 if (redirection->flags & LB_TARGET_CERTIFICATE)
1189 if (!redirection->TargetCertificate)
1190 flags |= LB_TARGET_CERTIFICATE;
1198BOOL redirection_set_flags(rdpRedirection* redirection, UINT32 flags)
1200 WINPR_ASSERT(redirection);
1201 redirection->flags = flags;
1205BOOL redirection_set_session_id(rdpRedirection* redirection, UINT32 session_id)
1207 WINPR_ASSERT(redirection);
1208 redirection->sessionID = session_id;
1212static BOOL redirection_unsupported(
const char* fkt, UINT32 flag, UINT32 mask)
1214 char buffer[1024] = { 0 };
1215 char buffer2[1024] = { 0 };
1216 WLog_WARN(TAG,
"[%s] supported flags are {%s}, have {%s}", fkt,
1217 rdp_redirection_flags_to_string(mask, buffer,
sizeof(buffer)),
1218 rdp_redirection_flags_to_string(flag, buffer2,
sizeof(buffer2)));
1222BOOL redirection_set_byte_option(rdpRedirection* redirection, UINT32 flag,
const BYTE* data,
1225 WINPR_ASSERT(redirection);
1228 case LB_CLIENT_TSV_URL:
1229 return redirection_copy_data(&redirection->TsvUrl, &redirection->TsvUrlLength, data,
1232 return redirection_copy_data(&redirection->Password, &redirection->PasswordLength, data,
1234 case LB_LOAD_BALANCE_INFO:
1235 return redirection_copy_data(&redirection->LoadBalanceInfo,
1236 &redirection->LoadBalanceInfoLength, data, length);
1237 case LB_REDIRECTION_GUID:
1238 return redirection_copy_data(&redirection->RedirectionGuid,
1239 &redirection->RedirectionGuidLength, data, length);
1240 case LB_TARGET_CERTIFICATE:
1241 return rdp_redirection_read_target_cert(&redirection->TargetCertificate, data, length);
1243 return redirection_unsupported(__func__, flag,
1244 LB_CLIENT_TSV_URL | LB_PASSWORD | LB_LOAD_BALANCE_INFO |
1245 LB_REDIRECTION_GUID | LB_TARGET_CERTIFICATE);
1249BOOL redirection_set_string_option(rdpRedirection* redirection, UINT32 flag,
const char* str)
1251 WINPR_ASSERT(redirection);
1255 return redirection_copy_string(&redirection->Username, str);
1257 return redirection_copy_string(&redirection->Domain, str);
1258 case LB_TARGET_FQDN:
1259 return redirection_copy_string(&redirection->TargetFQDN, str);
1260 case LB_TARGET_NETBIOS_NAME:
1261 return redirection_copy_string(&redirection->TargetNetBiosName, str);
1262 case LB_TARGET_NET_ADDRESS:
1263 return redirection_copy_string(&redirection->TargetNetAddress, str);
1265 return redirection_unsupported(__func__, flag,
1266 LB_USERNAME | LB_DOMAIN | LB_TARGET_FQDN |
1267 LB_TARGET_NETBIOS_NAME | LB_TARGET_NET_ADDRESS);
1271BOOL redirection_set_array_option(rdpRedirection* redirection, UINT32 flag,
const char** str,
1274 WINPR_ASSERT(redirection);
1277 case LB_TARGET_NET_ADDRESSES:
1278 return redirection_copy_array(&redirection->TargetNetAddresses,
1279 &redirection->TargetNetAddressesCount, str, count);
1281 return redirection_unsupported(__func__, flag, LB_TARGET_NET_ADDRESSES);
FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.
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_pointer_len(rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id, const void *data, size_t len)
Set a pointer to value data.
FREERDP_API BOOL freerdp_settings_set_pointer(rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id, const void *data)
Set a pointer to value data.
FREERDP_API const void * freerdp_settings_get_pointer(const rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id)
Returns a immutable pointer settings value.
FREERDP_API BOOL freerdp_settings_set_string_len(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const char *param, size_t len)
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.