Skip to content

Commit

Permalink
Refactored capability parsing
Browse files Browse the repository at this point in the history
* Add new settings for previously ignored capability options
* Store raw capability data in settings for later use
* Add function to extract settings from raw capability data
* Split capability read/write from client/server logic (e.g. enforce
  limits, ...)
  • Loading branch information
akallabeth committed Nov 3, 2022
1 parent b5e8b41 commit 7cef0cb
Show file tree
Hide file tree
Showing 8 changed files with 1,091 additions and 441 deletions.
44 changes: 31 additions & 13 deletions include/freerdp/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -790,6 +790,8 @@ typedef struct
#define FreeRDP_RemoteApplicationWorkingDir (2128)
#define FreeRDP_ReceivedCapabilities (2240)
#define FreeRDP_ReceivedCapabilitiesSize (2241)
#define FreeRDP_ReceivedCapabilityData (2242)
#define FreeRDP_ReceivedCapabilityDataSizes (2243)
#define FreeRDP_OsMajorType (2304)
#define FreeRDP_OsMinorType (2305)
#define FreeRDP_RefreshRect (2306)
Expand All @@ -799,6 +801,11 @@ typedef struct
#define FreeRDP_LongCredentialsSupported (2310)
#define FreeRDP_NoBitmapCompressionHeader (2311)
#define FreeRDP_BitmapCompressionDisabled (2312)
#define FreeRDP_CapsProtocolVersion (2313)
#define FreeRDP_CapsGeneralCompressionTypes (2314)
#define FreeRDP_CapsUpdateCapabilityFlag (2315)
#define FreeRDP_CapsRemoteUnshareFlag (2316)
#define FreeRDP_CapsGeneralCompressionLevel (2317)
#define FreeRDP_DesktopResize (2368)
#define FreeRDP_DrawAllowDynamicColorFidelity (2369)
#define FreeRDP_DrawAllowColorSubsampling (2370)
Expand Down Expand Up @@ -1209,13 +1216,13 @@ struct rdp_settings
ALIGN64 char* CertificateName; /* 1409 */
ALIGN64 char* CertificateFile; /* 1410 */
ALIGN64 char* PrivateKeyFile; /* 1411 */
UINT64 padding1412[1]; /* 1412 */
UINT64 padding1412[1413 - 1412]; /* 1412 */
ALIGN64 rdpRsaKey* RdpServerRsaKey; /* 1413 */
ALIGN64 rdpCertificate* RdpServerCertificate; /* 1414 */
ALIGN64 BOOL ExternalCertificateManagement; /* 1415 */
ALIGN64 char* CertificateContent; /* 1416 */
ALIGN64 char* PrivateKeyContent; /* 1417 */
UINT64 padding1418[1]; /* 1418 */
UINT64 padding1418[1419 - 1418]; /* 1418 */
ALIGN64 BOOL AutoAcceptCertificate; /* 1419 */
ALIGN64 BOOL AutoDenyCertificate; /* 1420 */
ALIGN64 char* CertificateAcceptedFingerprints; /* 1421 */
Expand Down Expand Up @@ -1356,19 +1363,26 @@ struct rdp_settings
/* Capabilities */
ALIGN64 BYTE* ReceivedCapabilities; /* 2240 */
ALIGN64 UINT32 ReceivedCapabilitiesSize; /* 2241 */
UINT64 padding2304[2304 - 2242]; /* 2242 */
ALIGN64 BYTE** ReceivedCapabilityData; /* 2242 */
ALIGN64 UINT32* ReceivedCapabilityDataSizes; /* 2243 */
UINT64 padding2304[2304 - 2244]; /* 2244 */

/* General Capabilities */
ALIGN64 UINT32 OsMajorType; /* 2304 */
ALIGN64 UINT32 OsMinorType; /* 2305 */
ALIGN64 BOOL RefreshRect; /* 2306 */
ALIGN64 BOOL SuppressOutput; /* 2307 */
ALIGN64 BOOL FastPathOutput; /* 2308 */
ALIGN64 BOOL SaltedChecksum; /* 2309 */
ALIGN64 BOOL LongCredentialsSupported; /* 2310 */
ALIGN64 BOOL NoBitmapCompressionHeader; /* 2311 */
ALIGN64 BOOL BitmapCompressionDisabled; /* 2312 */
UINT64 padding2368[2368 - 2313]; /* 2313 */
ALIGN64 UINT32 OsMajorType; /* 2304 */
ALIGN64 UINT32 OsMinorType; /* 2305 */
ALIGN64 BOOL RefreshRect; /* 2306 */
ALIGN64 BOOL SuppressOutput; /* 2307 */
ALIGN64 BOOL FastPathOutput; /* 2308 */
ALIGN64 BOOL SaltedChecksum; /* 2309 */
ALIGN64 BOOL LongCredentialsSupported; /* 2310 */
ALIGN64 BOOL NoBitmapCompressionHeader; /* 2311 */
ALIGN64 BOOL BitmapCompressionDisabled; /* 2312 */
ALIGN64 UINT16 CapsProtocolVersion; /* 2313 */
ALIGN64 UINT16 CapsGeneralCompressionTypes; /* 2314 */
ALIGN64 UINT16 CapsUpdateCapabilityFlag; /* 2315 */
ALIGN64 UINT16 CapsRemoteUnshareFlag; /* 2316 */
ALIGN64 UINT16 CapsGeneralCompressionLevel; /* 2317 */
UINT64 padding2368[2368 - 2318]; /* 2318 */

/* Bitmap Capabilities */
ALIGN64 BOOL DesktopResize; /* 2368 */
Expand Down Expand Up @@ -1834,6 +1848,10 @@ extern "C"
FREERDP_API const char* freerdp_settings_get_name_for_key(size_t key);
FREERDP_API UINT32 freerdp_settings_get_codecs_flags(const rdpSettings* settings);

FREERDP_API BOOL freerdp_settings_update_from_caps(rdpSettings* settings, BYTE* capsFlags,
BYTE** capsData, UINT32* capsSizes,
UINT32 capsCount, BOOL serverReceivedCaps);

FREERDP_API const char* freerdp_settings_get_server_name(const rdpSettings* settings);

FREERDP_API char* freerdp_rail_support_flags_to_string(UINT32 flags, char* buffer,
Expand Down
69 changes: 68 additions & 1 deletion libfreerdp/common/settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

#include "../core/settings.h"
#include "../core/certificate.h"
#include "../core/capabilities.h"
#include <freerdp/settings.h>
#include <freerdp/freerdp.h>
#include <freerdp/log.h>
Expand Down Expand Up @@ -823,10 +824,25 @@ void freerdp_dynamic_channel_collection_free(rdpSettings* settings)

void freerdp_capability_buffer_free(rdpSettings* settings)
{
UINT32 x;

WINPR_ASSERT(settings);

if (settings->ReceivedCapabilityData)
{
for (x = 0; x < settings->ReceivedCapabilitiesSize; x++)
{
free(settings->ReceivedCapabilityData[x]);
settings->ReceivedCapabilityData[x] = NULL;
}
}
settings->ReceivedCapabilitiesSize = 0;

free(settings->ReceivedCapabilityDataSizes);
settings->ReceivedCapabilityDataSizes = NULL;

free(settings->ReceivedCapabilityData);
settings->ReceivedCapabilityData = NULL;
free(settings->ReceivedCapabilities);
settings->ReceivedCapabilities = NULL;
}
Expand All @@ -841,8 +857,29 @@ BOOL freerdp_capability_buffer_copy(rdpSettings* settings, const rdpSettings* sr

for (UINT32 x = 0; x < src->ReceivedCapabilitiesSize; x++)
{
void* tmp;

WINPR_ASSERT(settings->ReceivedCapabilities);
settings->ReceivedCapabilities[x] = src->ReceivedCapabilities[x];

WINPR_ASSERT(settings->ReceivedCapabilityDataSizes);
settings->ReceivedCapabilityDataSizes[x] = src->ReceivedCapabilityDataSizes[x];

WINPR_ASSERT(settings->ReceivedCapabilityData);
if (src->ReceivedCapabilityDataSizes[x] > 0)
{
tmp = realloc(settings->ReceivedCapabilityData[x],
settings->ReceivedCapabilityDataSizes[x]);
if (!tmp)
return FALSE;
memcpy(tmp, src->ReceivedCapabilityData[x], src->ReceivedCapabilityDataSizes[x]);
settings->ReceivedCapabilityData[x] = tmp;
}
else
{
free(settings->ReceivedCapabilityData[x]);
settings->ReceivedCapabilityData[x] = NULL;
}
}
return TRUE;
}
Expand Down Expand Up @@ -1338,6 +1375,11 @@ BOOL freerdp_settings_set_pointer_len(rdpSettings* settings, size_t id, const vo
freerdp_dynamic_channel_collection_free(settings);
return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_DynamicChannelArraySize,
data, len, sizeof(ADDIN_ARGV*));
case FreeRDP_ReceivedCapabilityData:
if (data == NULL)
freerdp_capability_buffer_free(settings);
return freerdp_settings_set_pointer_len_(settings, id, FreeRDP_ReceivedCapabilitiesSize,
data, len, sizeof(BYTE*));
case FreeRDP_ReceivedCapabilities:
if (data == NULL)
freerdp_capability_buffer_free(settings);
Expand Down Expand Up @@ -1476,7 +1518,7 @@ void* freerdp_settings_get_pointer_array_writable(const rdpSettings* settings, s
max = freerdp_settings_get_uint32(settings, FreeRDP_TargetNetAddressCount);
if (offset >= max)
goto fail;
return &settings->TargetNetPorts[offset];
return settings->TargetNetPorts[offset];
case FreeRDP_ClientTimeZone:
max = 1;
if (offset >= max)
Expand Down Expand Up @@ -1850,6 +1892,31 @@ char* freerdp_rail_support_flags_to_string(UINT32 flags, char* buffer, size_t le
return buffer;
}

BOOL freerdp_settings_update_from_caps(rdpSettings* settings, BYTE* capsFlags, BYTE** capsData,
UINT32* capsSizes, UINT32 capsCount, BOOL serverReceivedCaps)
{
UINT32 x;
WINPR_ASSERT(settings);
WINPR_ASSERT(capsFlags || (capsCount == 0));
WINPR_ASSERT(capsData || (capsCount == 0));
WINPR_ASSERT(capsSizes || (capsCount == 0));
WINPR_ASSERT(capsCount <= UINT16_MAX);

for (x = 0; x < capsCount; x++)
{
if (capsFlags[x])
{
wStream buffer;
wStream* sub = Stream_StaticConstInit(&buffer, capsData[x], capsSizes[x]);

if (!rdp_read_capability_set(sub, (UINT16)x, settings, serverReceivedCaps))
return FALSE;
}
}

return TRUE;
}

const char* freerdp_rdp_version_string(UINT32 version)
{
switch (version)
Expand Down
49 changes: 49 additions & 0 deletions libfreerdp/common/settings_getters.c
Original file line number Diff line number Diff line change
Expand Up @@ -1282,6 +1282,21 @@ UINT16 freerdp_settings_get_uint16(const rdpSettings* settings, size_t id)

switch (id)
{
case FreeRDP_CapsGeneralCompressionLevel:
return settings->CapsGeneralCompressionLevel;

case FreeRDP_CapsGeneralCompressionTypes:
return settings->CapsGeneralCompressionTypes;

case FreeRDP_CapsProtocolVersion:
return settings->CapsProtocolVersion;

case FreeRDP_CapsRemoteUnshareFlag:
return settings->CapsRemoteUnshareFlag;

case FreeRDP_CapsUpdateCapabilityFlag:
return settings->CapsUpdateCapabilityFlag;

case FreeRDP_DesktopOrientation:
return settings->DesktopOrientation;

Expand Down Expand Up @@ -1317,6 +1332,26 @@ BOOL freerdp_settings_set_uint16(rdpSettings* settings, size_t id, UINT16 val)

switch (id)
{
case FreeRDP_CapsGeneralCompressionLevel:
settings->CapsGeneralCompressionLevel = cnv.c;
break;

case FreeRDP_CapsGeneralCompressionTypes:
settings->CapsGeneralCompressionTypes = cnv.c;
break;

case FreeRDP_CapsProtocolVersion:
settings->CapsProtocolVersion = cnv.c;
break;

case FreeRDP_CapsRemoteUnshareFlag:
settings->CapsRemoteUnshareFlag = cnv.c;
break;

case FreeRDP_CapsUpdateCapabilityFlag:
settings->CapsUpdateCapabilityFlag = cnv.c;
break;

case FreeRDP_DesktopOrientation:
settings->DesktopOrientation = cnv.c;
break;
Expand Down Expand Up @@ -3276,6 +3311,12 @@ void* freerdp_settings_get_pointer_writable(rdpSettings* settings, size_t id)
case FreeRDP_ReceivedCapabilities:
return settings->ReceivedCapabilities;

case FreeRDP_ReceivedCapabilityData:
return settings->ReceivedCapabilityData;

case FreeRDP_ReceivedCapabilityDataSizes:
return settings->ReceivedCapabilityDataSizes;

case FreeRDP_RedirectionPassword:
return settings->RedirectionPassword;

Expand Down Expand Up @@ -3392,6 +3433,14 @@ BOOL freerdp_settings_set_pointer(rdpSettings* settings, size_t id, const void*
settings->ReceivedCapabilities = cnv.v;
break;

case FreeRDP_ReceivedCapabilityData:
settings->ReceivedCapabilityData = cnv.v;
break;

case FreeRDP_ReceivedCapabilityDataSizes:
settings->ReceivedCapabilityDataSizes = cnv.v;
break;

case FreeRDP_RedirectionPassword:
settings->RedirectionPassword = cnv.v;
break;
Expand Down
13 changes: 13 additions & 0 deletions libfreerdp/common/settings_str.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,15 @@ static const struct settings_str_entry settings_map[] = {
{ FreeRDP_WaitForOutputBufferFlush, FREERDP_SETTINGS_TYPE_BOOL,
"FreeRDP_WaitForOutputBufferFlush" },
{ FreeRDP_Workarea, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_Workarea" },
{ FreeRDP_CapsGeneralCompressionLevel, FREERDP_SETTINGS_TYPE_UINT16,
"FreeRDP_CapsGeneralCompressionLevel" },
{ FreeRDP_CapsGeneralCompressionTypes, FREERDP_SETTINGS_TYPE_UINT16,
"FreeRDP_CapsGeneralCompressionTypes" },
{ FreeRDP_CapsProtocolVersion, FREERDP_SETTINGS_TYPE_UINT16, "FreeRDP_CapsProtocolVersion" },
{ FreeRDP_CapsRemoteUnshareFlag, FREERDP_SETTINGS_TYPE_UINT16,
"FreeRDP_CapsRemoteUnshareFlag" },
{ FreeRDP_CapsUpdateCapabilityFlag, FREERDP_SETTINGS_TYPE_UINT16,
"FreeRDP_CapsUpdateCapabilityFlag" },
{ FreeRDP_DesktopOrientation, FREERDP_SETTINGS_TYPE_UINT16, "FreeRDP_DesktopOrientation" },
{ FreeRDP_ProxyPort, FREERDP_SETTINGS_TYPE_UINT16, "FreeRDP_ProxyPort" },
{ FreeRDP_TLSMaxVersion, FREERDP_SETTINGS_TYPE_UINT16, "FreeRDP_TLSMaxVersion" },
Expand Down Expand Up @@ -523,6 +532,10 @@ static const struct settings_str_entry settings_map[] = {
{ FreeRDP_RdpServerCertificate, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_RdpServerCertificate" },
{ FreeRDP_RdpServerRsaKey, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_RdpServerRsaKey" },
{ FreeRDP_ReceivedCapabilities, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_ReceivedCapabilities" },
{ FreeRDP_ReceivedCapabilityData, FREERDP_SETTINGS_TYPE_POINTER,
"FreeRDP_ReceivedCapabilityData" },
{ FreeRDP_ReceivedCapabilityDataSizes, FREERDP_SETTINGS_TYPE_POINTER,
"FreeRDP_ReceivedCapabilityDataSizes" },
{ FreeRDP_RedirectionPassword, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_RedirectionPassword" },
{ FreeRDP_RedirectionTsvUrl, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_RedirectionTsvUrl" },
{ FreeRDP_ServerAutoReconnectCookie, FREERDP_SETTINGS_TYPE_POINTER,
Expand Down

0 comments on commit 7cef0cb

Please sign in to comment.