Skip to content

Instantly share code, notes, and snippets.

@nedix
Created October 4, 2024 23:18
Show Gist options
  • Save nedix/dac37525e4cbd1ceacc5b73a19eeded4 to your computer and use it in GitHub Desktop.
Save nedix/dac37525e4cbd1ceacc5b73a19eeded4 to your computer and use it in GitHub Desktop.
Conflicts xrdp_sec.c
From 8161651a92b3e04be0a8e4e6a20b52d8d7355157 Mon Sep 17 00:00:00 2001
From: NEDIX <[email protected]>
Date: Sat, 5 Oct 2024 01:16:58 +0200
Subject: [PATCH] Conflicts xrdp_sec.c
---
libxrdp/xrdp_sec.c | 137 ++++++++++++++++++++++++---------------------
1 file changed, 72 insertions(+), 65 deletions(-)
diff --git libxrdp/xrdp_sec.c libxrdp/xrdp_sec.c
index 596a4d53..509ac998 100644
--- libxrdp/xrdp_sec.c
+++ libxrdp/xrdp_sec.c
@@ -1117,22 +1117,33 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
}
/* TS_EXTENDED_INFO_PACKET required fields */
in_uint8s(s, 2); /* clientAddressFamily */
- in_uint16_le(s, len_ip);
- if (unicode_utf16_in(s, len_ip - 2, tmpdata, sizeof(tmpdata) - 1) != 0)
+ in_uint16_le(s, len_clnt_addr);
+ if (len_clnt_addr > EXTENDED_INFO_MAX_CLIENT_ADDR_LENGTH ||
+ !s_check_rem(s, len_clnt_addr))
{
- LOG(LOG_LEVEL_ERROR, "ERROR reading ip");
+ LOG(LOG_LEVEL_ERROR, "clientAddress is too long (%u bytes)",
+ len_clnt_addr);
return 1;
}
+ // The clientAddress is currently unused. [MS-RDPBCGR] requires
+ // a mandatory null terminator, but some clients set
+ // len_clnt_addr == 0 if this field is missing. Allow for this
+ // in any future implementation.
+ in_uint8s(s, len_clnt_addr); // Skip Unicode clientAddress
+
if (!s_check_rem_and_log(s, 2, "Parsing [MS-RDPBCGR] TS_EXTENDED_INFO_PACKET clientDir"))
{
return 1;
}
- in_uint16_le(s, len_dll);
- if (unicode_utf16_in(s, len_dll - 2, tmpdata, sizeof(tmpdata) - 1) != 0)
+ in_uint16_le(s, len_clnt_dir);
+ if (len_clnt_dir > INFO_CLIENT_MAX_CB_LEN ||
+ !s_check_rem(s, len_clnt_dir))
{
- LOG(LOG_LEVEL_ERROR, "ERROR reading clientDir");
+ LOG(LOG_LEVEL_ERROR, "clientDir is too long (%u bytes)", len_clnt_dir);
return 1;
}
+ in_uint8s(s, len_clnt_dir); // Skip Unicode clientDir
+
LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_EXTENDED_INFO_PACKET "
"<Required Fields> clientAddressFamily (ignored), "
"cbClientAddress (ignored), clientAddress (ignored), "
@@ -1225,45 +1236,34 @@ xrdp_sec_send_lic_response(struct xrdp_sec *self)
return 1;
}
- out_uint8a(s, g_lic2, sizeof(g_lic2));
+ /* [MS-RDPBCGR] TS_SECURITY_HEADER */
+ /* A careful reading of [MS-RDPBCGR] 2.2.1.12 shows that a securityHeader
+ * MUST be included, and provided the flag fields of the header does
+ * not contain SEC_ENCRYPT, it is always possible to send a basic
+ * security header */
+ out_uint16_le(s, SEC_LICENSE_PKT | SEC_LICENSE_ENCRYPT_CS); /* flags */
+ out_uint16_le(s, 0); /* flagsHi */
+
+ /* [MS-RDPBCGR] LICENSE_VALID_CLIENT_DATA */
+ /* preamble (LICENSE_PREAMBLE) */
+ out_uint8(s, ERROR_ALERT);
+ out_uint8(s, PREAMBLE_VERSION_3_0);
+ out_uint16_le(s, 16); /* Message size, including pre-amble */
+
+ /* validClientMessage */
+ /* From [MS-RDPBCGR] 2.2.12.1, dwStateTransition must be ST_NO_TRANSITION,
+ * and the bbErrorInfo field must contain an empty blob of type
+ * BB_ERROR_BLOB */
+ out_uint32_le(s, STATUS_VALID_CLIENT); /* dwErrorCode */
+ out_uint32_le(s, ST_NO_TRANSITION); /* dwStateTransition */
+ out_uint16_le(s, BB_ERROR_BLOB); /* wBlobType */
+ out_uint16_le(s, 0); /* wBlobLen */
s_mark_end(s);
- LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPELE] LICENSE_ERROR_MESSAGE with STATUS_VALID_CLIENT");
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] Server License Error PDU with STATUS_VALID_CLIENT");
if (xrdp_mcs_send(self->mcs_layer, s, MCS_GLOBAL_CHANNEL) != 0)
{
- LOG(LOG_LEVEL_ERROR, "Sending [MS-RDPELE] LICENSE_ERROR_MESSAGE with STATUS_VALID_CLIENT failed");
- free_stream(s);
- return 1;
- }
-
- free_stream(s);
- return 0;
-}
-
-/*****************************************************************************/
-/* returns error */
-static int
-xrdp_sec_send_media_lic_response(struct xrdp_sec *self)
-{
- struct stream *s;
-
- make_stream(s);
- init_stream(s, 8192);
-
- if (xrdp_mcs_init(self->mcs_layer, s) != 0)
- {
- LOG(LOG_LEVEL_ERROR, "xrdp_sec_send_media_lic_response: xrdp_mcs_init failed");
- free_stream(s);
- return 1;
- }
-
- out_uint8a(s, g_lic3, sizeof(g_lic3));
- s_mark_end(s);
-
- LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPELE] LICENSE_ERROR_MESSAGE with STATUS_VALID_CLIENT");
- if (xrdp_mcs_send(self->mcs_layer, s, MCS_GLOBAL_CHANNEL) != 0)
- {
- LOG(LOG_LEVEL_ERROR, "Sending [MS-RDPELE] LICENSE_ERROR_MESSAGE with STATUS_VALID_CLIENT failed");
+ LOG(LOG_LEVEL_ERROR, "Sending [MS-RDPBCGR] Server License Error PDU with STATUS_VALID_CLIENT failed");
free_stream(s);
return 1;
}
@@ -1632,7 +1632,7 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan)
}
}
- if (flags & SEC_CLIENT_RANDOM) /* 0x01 TS_SECURITY_PACKET */
+ if (flags & SEC_EXCHANGE_PKT) /* 0x01 TS_SECURITY_PACKET */
{
if (!s_check_rem_and_log(s, 4, "Parsing [MS-RDPBCGR] TS_SECURITY_PACKET"))
{
@@ -1671,7 +1671,7 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan)
return 0;
}
- if (flags & SEC_LOGON_INFO) /* 0x40 SEC_INFO_PKT */
+ if (flags & SEC_INFO_PKT)
{
if (xrdp_sec_process_logon_info(self, s) != 0)
{
@@ -2145,20 +2145,36 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec *self, struct stream *s)
LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_CORE "
"<Optional Field> earlyCapabilityFlags 0x%4.4x",
earlyCapabilityFlags);
- if ((earlyCapabilityFlags & 0x0002) && (supportedColorDepths & 0x0008))
+ if ((earlyCapabilityFlags & RNS_UD_CS_WANT_32BPP_SESSION)
+ && (supportedColorDepths & RNS_UD_32BPP_SUPPORT))
{
client_info->bpp = 32;
}
- if (earlyCapabilityFlags & 0x100) /* RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL */
+#ifdef XRDP_RFXCODEC
+ if (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL)
{
- LOG_DEVEL(LOG_LEVEL_INFO, "client supports gfx");
- self->rdp_layer->client_info.gfx = 1;
+ if (client_info->bpp < 32)
+ {
+ LOG(LOG_LEVEL_WARNING,
+ "client requested gfx protocol with insufficient color depth");
+ }
+ else if (client_info->max_bpp > 0 && client_info->max_bpp < 32)
+ {
+ LOG(LOG_LEVEL_WARNING, "Client requested gfx protocol "
+ "but the server configuration is limited to %d bpp.",
+ client_info->max_bpp);
+ }
+ else
+ {
+ LOG(LOG_LEVEL_INFO, "client supports gfx protocol");
+ self->rdp_layer->client_info.gfx = 1;
+ }
}
else
{
LOG_DEVEL(LOG_LEVEL_INFO, "client DOES NOT support gfx");
}
-
+#endif
if (!s_check_rem(s, 64))
{
return 0;
@@ -2689,8 +2705,6 @@ xrdp_sec_in_mcs_data(struct xrdp_sec *self)
{
struct stream *s = (struct stream *)NULL;
struct xrdp_client_info *client_info = (struct xrdp_client_info *)NULL;
- int index = 0;
- char c = 0;
client_info = &(self->rdp_layer->client_info);
s = &(self->client_mcs_data);
@@ -2703,23 +2717,16 @@ xrdp_sec_in_mcs_data(struct xrdp_sec *self)
in_uint8s(s, 47); /* skip [ITU T.124] ConferenceCreateRequest up to the
userData field, and skip [MS-RDPBCGR] TS_UD_CS_CORE
up to the clientName field */
- g_memset(client_info->hostname, 0, 32);
- c = 1;
- index = 0;
-
- /* TODO: why aren't we using unicode_utf16_in to parse the client name
- like we do in xrdp_sec_process_mcs_data_CS_CORE? */
- while (index < 16 && c != 0)
+ if (!s_check_rem_and_log(s, INFO_CLIENT_NAME_BYTES,
+ "Parsing [MS-RDPBCGR] TS_UD_CS_CORE clientName"))
{
- if (!s_check_rem_and_log(s, 2, "Parsing [MS-RDPBCGR] TS_UD_CS_CORE clientName"))
- {
- return 1;
- }
- in_uint8(s, c);
- in_uint8s(s, 1);
- client_info->hostname[index] = c;
- index++;
+ return 1;
}
+ in_utf16_le_fixed_as_utf8(s, (INFO_CLIENT_NAME_BYTES - 2) / 2,
+ client_info->hostname,
+ sizeof(client_info->hostname));
+ in_uint8s(s, 2); /* Ignored - terminator for full-size clientName */
+
/* get build */
s->p = s->data;
if (!s_check_rem_and_log(s, 43 + 4, "Parsing [MS-RDPBCGR] TS_UD_CS_CORE clientBuild"))
--
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment