From 856dd963126d8e3e53d172529b1d1311f13a2c96 Mon Sep 17 00:00:00 2001 From: akallabeth Date: Tue, 18 Feb 2025 15:06:46 +0100 Subject: [PATCH] [channel,rdpdr] support general caps V1 [MS-RDPEFS] 2.2.2.7.1 General Capability Set (GENERAL_CAPS_SET) requires that the SpecialTypeDeviceCap element is not available if the version is GENERAL_CAPABILITY_VERSION_01 --- channels/rdpdr/client/rdpdr_capabilities.c | 40 ++++++++++++---------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/channels/rdpdr/client/rdpdr_capabilities.c b/channels/rdpdr/client/rdpdr_capabilities.c index 769973215..7d807b5fa 100644 --- a/channels/rdpdr/client/rdpdr_capabilities.c +++ b/channels/rdpdr/client/rdpdr_capabilities.c @@ -77,31 +77,35 @@ static UINT rdpdr_process_general_capset(rdpdrPlugin* rdpdr, wStream* s, { WINPR_ASSERT(header); - if (header->CapabilityLength != 36) + const BOOL gotV1 = header->Version == GENERAL_CAPABILITY_VERSION_01; + const size_t expect = gotV1 ? 32 : 36; + if (header->CapabilityLength != expect) { WLog_Print(rdpdr->log, WLOG_ERROR, - "CAP_GENERAL_TYPE::CapabilityLength expected 36, got %" PRIu32, + "CAP_GENERAL_TYPE::CapabilityLength expected %" PRIuz ", got %" PRIu32, expect, header->CapabilityLength); return ERROR_INVALID_DATA; } - if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, 36)) + if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, expect)) return ERROR_INVALID_DATA; - Stream_Read_UINT32(s, rdpdr->serverOsType); /* osType, ignored on receipt */ - Stream_Read_UINT32(s, rdpdr->serverOsVersion); /* osVersion, unused and must be set to zero */ - Stream_Read_UINT16(s, rdpdr->serverVersionMajor); /* protocolMajorVersion, must be set to 1 */ - Stream_Read_UINT16(s, rdpdr->serverVersionMinor); /* protocolMinorVersion */ - Stream_Read_UINT32(s, rdpdr->serverIOCode1); /* ioCode1 */ - Stream_Read_UINT32( - s, rdpdr->serverIOCode2); /* ioCode2, must be set to zero, reserved for future use */ - Stream_Read_UINT32(s, rdpdr->serverExtendedPDU); /* extendedPDU */ - Stream_Read_UINT32(s, rdpdr->serverExtraFlags1); /* extraFlags1 */ - Stream_Read_UINT32( - s, - rdpdr->serverExtraFlags2); /* extraFlags2, must be set to zero, reserved for future use */ - Stream_Read_UINT32( - s, rdpdr->serverSpecialTypeDeviceCap); /* SpecialTypeDeviceCap, number of special devices to - be redirected before logon */ + rdpdr->serverOsType = Stream_Get_UINT32(s); /* osType, ignored on receipt */ + rdpdr->serverOsVersion = Stream_Get_UINT32(s); /* osVersion, unused and must be set to zero */ + rdpdr->serverVersionMajor = Stream_Get_UINT16(s); /* protocolMajorVersion, must be set to 1 */ + rdpdr->serverVersionMinor = Stream_Get_UINT16(s); /* protocolMinorVersion */ + rdpdr->serverIOCode1 = Stream_Get_UINT32(s); /* ioCode1 */ + rdpdr->serverIOCode2 = + Stream_Get_UINT32(s); /* ioCode2, must be set to zero, reserved for future use */ + rdpdr->serverExtendedPDU = Stream_Get_UINT32(s); /* extendedPDU */ + rdpdr->serverExtraFlags1 = Stream_Get_UINT32(s); /* extraFlags1 */ + rdpdr->serverExtraFlags2 = + Stream_Get_UINT32(s); /* extraFlags2, must be set to zero, reserved for future use */ + if (gotV1) + rdpdr->serverSpecialTypeDeviceCap = 0; + else + rdpdr->serverSpecialTypeDeviceCap = Stream_Get_UINT32( + s); /* SpecialTypeDeviceCap, number of special devices to + be redirected before logon */ return CHANNEL_RC_OK; }