Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/neutrinolabs/xrdp.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraquesnel <131881+aquesnel@users.noreply.github.com>2021-02-04 13:11:54 +0300
committerGitHub <noreply@github.com>2021-02-04 13:11:54 +0300
commit0ec471b02dcab7152dbf954526f791dd0d98b8f7 (patch)
tree577c9634467bbf136bac2f9b427ccda24daf9fed /libxrdp
parent42150c5c4f887998bd4d3a7896af424e2f391184 (diff)
Add detailed logging to libxrdp (#1742)
* Added s_rem(s) for getting the remaining bytes in a stream * Added s_rem_out() macro * Fixed 15bpp pointer error checking * Combined the 512 and 2048 bit certificate sending code paths * Other detailed comments and logging added following MS-RDPBCGR
Diffstat (limited to 'libxrdp')
-rw-r--r--libxrdp/libxrdp.c220
-rw-r--r--libxrdp/libxrdp.h9
-rw-r--r--libxrdp/xrdp_caps.c268
-rw-r--r--libxrdp/xrdp_channel.c388
-rw-r--r--libxrdp/xrdp_fastpath.c57
-rw-r--r--libxrdp/xrdp_iso.c243
-rw-r--r--libxrdp/xrdp_mcs.c789
-rw-r--r--libxrdp/xrdp_mppc_enc.c12
-rw-r--r--libxrdp/xrdp_orders.c43
-rw-r--r--libxrdp/xrdp_orders_rail.c202
-rw-r--r--libxrdp/xrdp_rdp.c450
-rw-r--r--libxrdp/xrdp_sec.c871
12 files changed, 2672 insertions, 880 deletions
diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c
index f36ea40e..ec4aebed 100644
--- a/libxrdp/libxrdp.c
+++ b/libxrdp/libxrdp.c
@@ -132,19 +132,19 @@ libxrdp_force_read(struct trans *trans)
if (trans_force_read(trans, 4) != 0)
{
- LOG(LOG_LEVEL_WARNING, "libxrdp_force_read: header read error");
- return 0;
+ LOG(LOG_LEVEL_ERROR, "libxrdp_force_read: header read error");
+ return NULL;
}
bytes = libxrdp_get_pdu_bytes(s->data);
if (bytes < 4 || bytes > s->size)
{
- LOG(LOG_LEVEL_WARNING, "libxrdp_force_read: bad header length %d", bytes);
- return 0;
+ LOG(LOG_LEVEL_ERROR, "libxrdp_force_read: bad header length %d", bytes);
+ return NULL;
}
if (trans_force_read(trans, bytes - 4) != 0)
{
- LOG(LOG_LEVEL_WARNING, "libxrdp_force_read: Can't read PDU");
- return 0;
+ LOG(LOG_LEVEL_ERROR, "libxrdp_force_read: Can't read PDU");
+ return NULL;
}
return s;
}
@@ -234,12 +234,16 @@ libxrdp_process_data(struct xrdp_session *session, struct stream *s)
dead_lock_counter++;
break;
case PDUTYPE_CONFIRMACTIVEPDU:
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Processing received "
+ "[MS-RDPBCGR] PDUTYPE_CONFIRMACTIVEPDU");
xrdp_caps_process_confirm_active(rdp, s);
break;
case PDUTYPE_DATAPDU:
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Processing received "
+ "[MS-RDPBCGR] PDUTYPE_DATAPDU");
if (xrdp_rdp_process_data(rdp, s) != 0)
{
- LOG(LOG_LEVEL_ERROR, "libxrdp_process_data returned non zero");
+ LOG(LOG_LEVEL_ERROR, "libxrdp_process_data: xrdp_rdp_process_data failed");
cont = 0;
term = 1;
}
@@ -247,13 +251,13 @@ libxrdp_process_data(struct xrdp_session *session, struct stream *s)
case 2: /* FASTPATH_INPUT_EVENT */
if (xrdp_fastpath_process_input_event(rdp->sec_layer->fastpath_layer, s) != 0)
{
- LOG(LOG_LEVEL_ERROR, "libxrdp_process_data returned non zero");
+ LOG(LOG_LEVEL_ERROR, "libxrdp_process_data: xrdp_fastpath_process_input_event failed");
cont = 0;
term = 1;
}
break;
default:
- LOG(LOG_LEVEL_ERROR, "unknown in libxrdp_process_data: code= %d", code);
+ LOG(LOG_LEVEL_WARNING, "unknown code = %d (ignored)", code);
dead_lock_counter++;
break;
}
@@ -262,8 +266,9 @@ libxrdp_process_data(struct xrdp_session *session, struct stream *s)
{
/*This situation can happen and this is a workaround*/
cont = 0;
- LOG(LOG_LEVEL_ERROR, "Serious programming error: we were locked in a deadly loop");
- LOG(LOG_LEVEL_ERROR, "Remaining: %d", (int) (s->end - s->next_packet));
+ LOG(LOG_LEVEL_WARNING,
+ "Serious programming error: we were locked in a deadly loop. "
+ "Remaining bytes: %d", (int) (s->end - s->next_packet));
s->next_packet = 0;
}
@@ -292,7 +297,9 @@ libxrdp_send_palette(struct xrdp_session *session, int *palette)
return 0;
}
- LOG_DEVEL(LOG_LEVEL_TRACE, "libxrdp_send_palette sending palette");
+ LOG_DEVEL(LOG_LEVEL_DEBUG, "sending palette (%s)",
+ ((session->client_info->use_fast_path & 1) ?
+ "fastpath" : "slowpath"));
/* clear orders */
libxrdp_orders_force_send(session);
@@ -301,25 +308,25 @@ libxrdp_send_palette(struct xrdp_session *session, int *palette)
if (session->client_info->use_fast_path & 1) /* fastpath output supported */
{
- LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_palette: fastpath");
if (xrdp_rdp_init_fastpath((struct xrdp_rdp *)session->rdp, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "libxrdp_send_palette: xrdp_rdp_init_fastpath failed");
free_stream(s);
return 1;
}
}
else
{
- LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_palette: slowpath");
xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s);
}
/* TS_UPDATE_PALETTE_DATA */
- out_uint16_le(s, RDP_UPDATE_PALETTE);
- out_uint16_le(s, 0);
- out_uint16_le(s, 256); /* # of colors */
- out_uint16_le(s, 0);
+ out_uint16_le(s, RDP_UPDATE_PALETTE); /* updateType */
+ out_uint16_le(s, 0); /* pad2Octets */
+ out_uint16_le(s, 256); /* # of colors (low-bytes) */
+ out_uint16_le(s, 0); /* # of colors (high-bytes) */
+ /* paletteEntries */
for (i = 0; i < 256; i++)
{
color = palette[i];
@@ -331,15 +338,24 @@ libxrdp_send_palette(struct xrdp_session *session, int *palette)
s_mark_end(s);
if (session->client_info->use_fast_path & 1) /* fastpath output supported */
{
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_FP_UPDATE_PALETTE "
+ "paletteUpdateData = { updateType %d (UPDATETYPE_PALETTE), "
+ "pad2Octets <ignored>, numberColors 256, "
+ "paletteEntries <omitted from log> }", RDP_UPDATE_PALETTE);
if (xrdp_rdp_send_fastpath((struct xrdp_rdp *)session->rdp, s,
FASTPATH_UPDATETYPE_PALETTE) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "libxrdp_send_palette: xrdp_rdp_send_fastpath failed");
free_stream(s);
return 1;
}
}
else
{
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_UPDATE_PALETTE_DATA "
+ "updateType %d (UPDATETYPE_PALETTE), pad2Octets <ignored>, "
+ "numberColors 256, paletteEntries <omitted from log>",
+ RDP_UPDATE_PALETTE);
xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s,
RDP_DATA_PDU_UPDATE);
}
@@ -364,14 +380,12 @@ libxrdp_send_bell(struct xrdp_session *session)
{
struct stream *s = (struct stream *)NULL;
- LOG_DEVEL(LOG_LEVEL_TRACE, "libxrdp_send_bell sending bell signal");
- /* see MS documentation: Server play sound PDU, TS_PLAY_SOUND_PDU_DATA */
-
make_stream(s);
init_stream(s, 8192);
if (xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "libxrdp_send_bell: xrdp_rdp_init_data failed");
free_stream(s);
return 1;
}
@@ -384,6 +398,7 @@ libxrdp_send_bell(struct xrdp_session *session)
if (xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s, RDP_DATA_PDU_PLAY_SOUND) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "libxrdp_send_bell: xrdp_rdp_send_data failed");
free_stream(s);
return 1;
}
@@ -461,7 +476,7 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
total_bufsize = 0;
num_updates = 0;
xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s);
- out_uint16_le(s, RDP_UPDATE_BITMAP);
+ out_uint16_le(s, RDP_UPDATE_BITMAP); /* updateType */
p_num_updates = s->p;
out_uint8s(s, 2); /* num_updates set later */
@@ -564,6 +579,11 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
p_num_updates[0] = num_updates;
p_num_updates[1] = num_updates >> 8;
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_UPDATE_BITMAP_DATA "
+ "updateType %d (UPDATETYPE_BITMAP), numberRectangles %d, "
+ "rectangles <omitted from log>",
+ RDP_UPDATE_BITMAP, num_updates);
+
xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s,
RDP_DATA_PDU_UPDATE);
@@ -668,6 +688,10 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
}
s_mark_end(s);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_UPDATE_BITMAP_DATA "
+ "updateType %d (UPDATETYPE_BITMAP), numberRectangles 1, "
+ "rectangles <omitted from log>",
+ RDP_UPDATE_BITMAP);
xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s,
RDP_DATA_PDU_UPDATE);
i = i + lines_sending;
@@ -692,7 +716,7 @@ libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
int j;
int data_bytes;
- LOG_DEVEL(LOG_LEVEL_TRACE, "libxrdp_send_pointer sending cursor");
+ LOG_DEVEL(LOG_LEVEL_DEBUG, "sending cursor");
if (bpp == 0)
{
bpp = 24;
@@ -702,14 +726,17 @@ libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
{
if (bpp != 24)
{
- LOG(LOG_LEVEL_ERROR, "libxrdp_send_pointer: error client does not support "
- "new cursors and bpp is %d", bpp);
+ LOG(LOG_LEVEL_ERROR, "Send pointer: client does not support "
+ "new cursors. The only valid bpp is 24, received %d", bpp);
return 1;
}
}
- if ((bpp == 15) && (bpp != 16) && (bpp != 24) && (bpp != 32))
+
+ if ((bpp != 16) && (bpp != 24) && (bpp != 32))
{
- LOG(LOG_LEVEL_ERROR, "libxrdp_send_pointer: error");
+ LOG(LOG_LEVEL_ERROR,
+ "Send pointer: invalid bpp value. Expected 16 or 24 or 32, "
+ "received %d", bpp);
return 1;
}
make_stream(s);
@@ -720,6 +747,7 @@ libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_pointer: fastpath");
if (xrdp_rdp_init_fastpath((struct xrdp_rdp *)session->rdp, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "libxrdp_send_pointer: xrdp_rdp_init_fastpath failed");
free_stream(s);
return 1;
}
@@ -731,7 +759,7 @@ libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
else
{
data_bytes = ((bpp + 7) / 8) * 32 * 32;
- out_uint16_le(s, bpp);
+ out_uint16_le(s, bpp); /* TS_FP_POINTERATTRIBUTE -> newPointerUpdateData.xorBpp */
}
}
else /* slowpath */
@@ -743,25 +771,34 @@ libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
out_uint16_le(s, RDP_POINTER_COLOR);
out_uint16_le(s, 0); /* pad */
data_bytes = 3072;
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPBCGR] TS_POINTER_PDU "
+ "messageType %d (TS_PTRMSGTYPE_COLOR), pad2Octets <ignored>",
+ RDP_POINTER_COLOR);
}
else
{
out_uint16_le(s, RDP_POINTER_POINTER);
out_uint16_le(s, 0); /* pad */
- out_uint16_le(s, bpp);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPBCGR] TS_POINTER_PDU "
+ "messageType %d (TS_PTRMSGTYPE_POINTER), pad2Octets <ignored>",
+ RDP_POINTER_POINTER);
+
+ out_uint16_le(s, bpp); /* TS_POINTERATTRIBUTE -> xorBpp */
data_bytes = ((bpp + 7) / 8) * 32 * 32;
}
}
-
- out_uint16_le(s, cache_idx); /* cache_idx */
- out_uint16_le(s, x);
- out_uint16_le(s, y);
- out_uint16_le(s, 32);
- out_uint16_le(s, 32);
- out_uint16_le(s, 128);
- out_uint16_le(s, data_bytes);
-
+ /* the TS_COLORPOINTERATTRIBUTE field which is shared by
+ all of the pointer attribute PDU types */
+ out_uint16_le(s, cache_idx); /* cache_idx */
+ out_uint16_le(s, x); /* hotSpot.xPos */
+ out_uint16_le(s, y); /* hotSpot.yPos */
+ out_uint16_le(s, 32); /* width */
+ out_uint16_le(s, 32); /* height */
+ out_uint16_le(s, 128); /* lengthAndMask */
+ out_uint16_le(s, data_bytes); /* lengthXorMask */
+
+ /* xorMaskData */
switch (bpp)
{
//case 15: /* coverity: this is logically dead code */
@@ -804,25 +841,42 @@ libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
break;
}
- out_uint8a(s, mask, 128); /* mask */
+ out_uint8a(s, mask, 128); /* andMaskData */
out_uint8(s, 0); /* pad */
s_mark_end(s);
if (session->client_info->use_fast_path & 1) /* fastpath output supported */
{
if ((session->client_info->pointer_flags & 1) == 0)
{
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_FP_COLORPOINTERATTRIBUTE "
+ "cachedPointerUpdateData = { cacheIndex %d, "
+ "hotSpot.xPos %d, hotSpot.yPos %d, width 32, "
+ "height 32, lengthAndMask 128, lengthXorMask %d, "
+ "xorMaskData <omitted from log>, "
+ "andMaskData <omitted from log> }",
+ cache_idx, x, y, data_bytes);
if (xrdp_rdp_send_fastpath((struct xrdp_rdp *)session->rdp, s,
FASTPATH_UPDATETYPE_COLOR) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "libxrdp_send_pointer: xrdp_rdp_send_fastpath failed");
free_stream(s);
return 1;
}
}
else
{
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_FP_POINTERATTRIBUTE "
+ "newPointerUpdateData.xorBpp %d, "
+ "newPointerUpdateData.colorPtrAttr = { cacheIndex %d, "
+ "hotSpot.xPos %d, hotSpot.yPos %d, width 32, "
+ "height 32, lengthAndMask 128, lengthXorMask %d, "
+ "xorMaskData <omitted from log>, "
+ "andMaskData <omitted from log> }",
+ bpp, cache_idx, x, y, data_bytes);
if (xrdp_rdp_send_fastpath((struct xrdp_rdp *)session->rdp, s,
FASTPATH_UPDATETYPE_POINTER) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "libxrdp_send_pointer: xrdp_rdp_send_fastpath failed");
free_stream(s);
return 1;
}
@@ -830,6 +884,26 @@ libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
}
else
{
+ if ((session->client_info->pointer_flags & 1) == 0)
+ {
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_COLORPOINTERATTRIBUTE "
+ "cacheIndex %d, "
+ "hotSpot.xPos %d, hotSpot.yPos %d, width 32, "
+ "height 32, lengthAndMask 128, lengthXorMask %d, "
+ "xorMaskData <omitted from log>, "
+ "andMaskData <omitted from log>",
+ cache_idx, x, y, data_bytes);
+ }
+ else
+ {
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_POINTERATTRIBUTE "
+ "xorBpp %d, colorPtrAttr = { cacheIndex %d, "
+ "hotSpot.xPos %d, hotSpot.yPos %d, width 32, "
+ "height 32, lengthAndMask 128, lengthXorMask %d, "
+ "xorMaskData <omitted from log>, "
+ "andMaskData <omitted from log> }",
+ bpp, cache_idx, x, y, data_bytes);
+ }
xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s,
RDP_DATA_PDU_POINTER);
}
@@ -843,26 +917,26 @@ libxrdp_set_pointer(struct xrdp_session *session, int cache_idx)
{
struct stream *s;
- LOG_DEVEL(LOG_LEVEL_TRACE, "libxrdp_set_pointer sending cursor index");
make_stream(s);
init_stream(s, 8192);
-
if (session->client_info->use_fast_path & 1) /* fastpath output supported */
{
- LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_pointer: fastpath");
if (xrdp_rdp_init_fastpath((struct xrdp_rdp *)session->rdp, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "libxrdp_set_pointer: xrdp_rdp_init_fastpath failed");
free_stream(s);
return 1;
}
}
else
{
- LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_pointer: slowpath");
xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s);
out_uint16_le(s, RDP_POINTER_CACHED);
out_uint16_le(s, 0); /* pad */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPBCGR] TS_POINTER_PDU "
+ "messageType %d (TS_PTRMSGTYPE_CACHED), pad2Octets <ignored>",
+ RDP_POINTER_CACHED);
}
out_uint16_le(s, cache_idx); /* cache_idx */
@@ -870,15 +944,20 @@ libxrdp_set_pointer(struct xrdp_session *session, int cache_idx)
if (session->client_info->use_fast_path & 1) /* fastpath output supported */
{
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_FP_CACHEDPOINTERATTRIBUTE "
+ "cachedPointerUpdateData.cacheIndex %d", cache_idx);
if (xrdp_rdp_send_fastpath((struct xrdp_rdp *)session->rdp, s,
FASTPATH_UPDATETYPE_CACHED) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "libxrdp_set_pointer: xrdp_rdp_send_fastpath failed");
free_stream(s);
return 1;
}
}
else
{
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_CACHEDPOINTERATTRIBUTE "
+ "cacheIndex %d", cache_idx);
xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s,
RDP_DATA_PDU_POINTER);
}
@@ -1086,12 +1165,14 @@ libxrdp_reset(struct xrdp_session *session,
}
else
{
+ LOG(LOG_LEVEL_ERROR, "libxrdp_reset: session->client_info is NULL");
return 1;
}
/* this will send any lingering orders */
if (xrdp_orders_reset((struct xrdp_orders *)session->orders) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "libxrdp_reset: xrdp_orders_reset failed");
return 1;
}
@@ -1103,12 +1184,14 @@ libxrdp_reset(struct xrdp_session *session,
session->check_for_app_input = 0;
if (xrdp_rdp_send_deactivate((struct xrdp_rdp *)session->rdp) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "libxrdp_reset: xrdp_rdp_send_deactivate failed");
return 1;
}
/* this should do the resizing */
if (xrdp_caps_send_demand_active((struct xrdp_rdp *)session->rdp) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "libxrdp_reset: xrdp_caps_send_demand_active failed");
return 1;
}
@@ -1178,24 +1261,26 @@ libxrdp_query_channel(struct xrdp_session *session, int index,
if (index < 0 || index >= count)
{
- LOG(LOG_LEVEL_ERROR, "libxrdp_query_channel - Channel out of range %d", index);
+ LOG(LOG_LEVEL_ERROR, "libxrdp_query_channel: Channel index out of range. "
+ "max channel index %d, received channel index %d",
+ count, index);
return 1;
}
channel_item = (struct mcs_channel_item *)
list_get_item(mcs->channel_list, index);
- if (channel_item == 0)
+ if (channel_item == NULL)
{
/* this should not happen */
- LOG(LOG_LEVEL_ERROR, "libxrdp_query_channel - channel item is 0");
+ LOG(LOG_LEVEL_ERROR, "libxrdp_query_channel - channel item is NULL");
return 1;
}
if (channel_name != 0)
{
g_strncpy(channel_name, channel_item->name, 8);
- LOG(LOG_LEVEL_ERROR, "libxrdp_query_channel - Channel %d name %s", index, channel_name);
+ LOG(LOG_LEVEL_DEBUG, "libxrdp_query_channel - Channel %d name %s", index, channel_name);
}
if (channel_flags != 0)
@@ -1265,6 +1350,7 @@ libxrdp_send_to_channel(struct xrdp_session *session, int channel_id,
if (xrdp_channel_init(chan, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "libxrdp_send_to_channel: xrdp_channel_init failed");
free_stream(s);
return 1;
}
@@ -1272,10 +1358,12 @@ libxrdp_send_to_channel(struct xrdp_session *session, int channel_id,
/* here we make a copy of the data */
out_uint8a(s, data, data_len);
s_mark_end(s);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] Virtual Channel PDU "
+ "data <omitted from log>");
if (xrdp_channel_send(chan, s, channel_id, total_data_len, flags) != 0)
{
- LOG(LOG_LEVEL_ERROR, "libxrdp_send_to_channel: error, server channel data NOT sent to client channel");
+ LOG(LOG_LEVEL_ERROR, "libxrdp_send_to_channel: xrdp_channel_send failed");
free_stream(s);
return 1;
}
@@ -1297,15 +1385,20 @@ libxrdp_disable_channel(struct xrdp_session *session, int channel_id,
mcs = rdp->sec_layer->mcs_layer;
if (mcs->channel_list == NULL)
{
+ LOG(LOG_LEVEL_ERROR, "Channel list is NULL");
return 1;
}
channel_item = (struct mcs_channel_item *)
list_get_item(mcs->channel_list, channel_id);
if (channel_item == NULL)
{
+ LOG(LOG_LEVEL_ERROR, "Channel item is NULL");
return 1;
}
channel_item->disabled = is_disabled;
+ LOG(LOG_LEVEL_DEBUG, "%s channel %d (%s)",
+ (is_disabled ? "Disabling" : "Enabling"), channel_item->chanid,
+ channel_item->name);
return 1;
}
@@ -1526,6 +1619,7 @@ libxrdp_fastpath_send_surface(struct xrdp_session *session,
LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_fastpath_send_surface:");
if ((session->client_info->use_fast_path & 1) == 0)
{
+ LOG(LOG_LEVEL_ERROR, "Sending data via fastpath is disabled");
return 1;
}
max_bytes = session->client_info->max_fastpath_frag_bytes;
@@ -1539,10 +1633,16 @@ libxrdp_fastpath_send_surface(struct xrdp_session *session,
cmd_bytes = 10 + 12;
if (data_bytes + rdp_bytes + sec_bytes + cmd_bytes > max_bytes)
{
+ LOG(LOG_LEVEL_ERROR, "Too much data to send via fastpath. "
+ "Max fastpath bytes %d, received bytes %d",
+ max_bytes, (data_bytes + rdp_bytes + sec_bytes + cmd_bytes));
return 1;
}
if (sec_bytes + rdp_bytes + cmd_bytes > pad_bytes)
{
+ LOG(LOG_LEVEL_ERROR, "Too much header to send via fastpath. "
+ "Max fastpath header bytes %d, received bytes %d",
+ pad_bytes, (rdp_bytes + sec_bytes + cmd_bytes));
return 1;
}
g_memset(&ls, 0, sizeof(ls));
@@ -1558,6 +1658,13 @@ libxrdp_fastpath_send_surface(struct xrdp_session *session,
out_uint16_le(s, destTop);
out_uint16_le(s, destRight);
out_uint16_le(s, destBottom);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_SURFCMD_STREAM_SURF_BITS "
+ "cmdType 0x%4.4x (CMDTYPE_STREAM_SURFACE_BITS), destLeft %d, "
+ "destTop %d, destRight %d, destBottom %d, "
+ "bitmapData <see TS_BITMAP_DATA_EX>",
+ CMDTYPE_STREAM_SURFACE_BITS, destLeft, destTop, destRight,
+ destBottom);
+
/* TS_BITMAP_DATA_EX */
out_uint8(s, bpp);
out_uint8(s, 0);
@@ -1566,9 +1673,17 @@ libxrdp_fastpath_send_surface(struct xrdp_session *session,
out_uint16_le(s, width);
out_uint16_le(s, height);
out_uint32_le(s, data_bytes);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding field bitmapData [MS-RDPBCGR] TS_BITMAP_DATA_EX "
+ "bpp %d, flags 0x00, reserved 0, codecID %d, width %d, "
+ "height %d, bitmapDataLength %d, exBitmapDataHeader <not present>, "
+ "bitmapData <omitted from log>",
+ bpp, codecID, width, height, data_bytes);
+
/* 4 = FASTPATH_UPDATETYPE_SURFCMDS */
if (xrdp_rdp_send_fastpath(rdp, s, 4) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "libxrdp_fastpath_send_surface: xrdp_rdp_send_fastpath failed");
return 1;
}
return 0;
@@ -1585,10 +1700,12 @@ libxrdp_fastpath_send_frame_marker(struct xrdp_session *session,
LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_fastpath_send_frame_marker:");
if ((session->client_info->use_fast_path & 1) == 0)
{
+ LOG(LOG_LEVEL_ERROR, "Sending data via fastpath is disabled");
return 1;
}
if (session->client_info->use_frame_acks == 0)
{
+ LOG(LOG_LEVEL_ERROR, "Fastpath frame acks is disabled");
return 1;
}
rdp = (struct xrdp_rdp *) (session->rdp);
@@ -1599,9 +1716,15 @@ libxrdp_fastpath_send_frame_marker(struct xrdp_session *session,
out_uint16_le(s, frame_action);
out_uint32_le(s, frame_id);
s_mark_end(s);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_FRAME_MARKER "
+ "cmdType 0x0004 (CMDTYPE_FRAME_MARKER), frameAction 0x%4.4x, "
+ "frameId %d", frame_action, frame_id);
+
/* 4 = FASTPATH_UPDATETYPE_SURFCMDS */
if (xrdp_rdp_send_fastpath(rdp, s, 4) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "libxrdp_fastpath_send_frame_marker: xrdp_rdp_send_fastpath failed");
free_stream(s);
return 1;
}
@@ -1616,7 +1739,6 @@ libxrdp_send_session_info(struct xrdp_session *session, const char *data,
{
struct xrdp_rdp *rdp;
- LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_session_info:");
rdp = (struct xrdp_rdp *) (session->rdp);
return xrdp_rdp_send_session_info(rdp, data, data_bytes);
}
diff --git a/libxrdp/libxrdp.h b/libxrdp/libxrdp.h
index 413a9e41..b0eae8c6 100644
--- a/libxrdp/libxrdp.h
+++ b/libxrdp/libxrdp.h
@@ -33,6 +33,7 @@
#include "file.h"
#include "libxrdpinc.h"
#include "xrdp_client_info.h"
+#include "log.h"
/* iso */
@@ -549,9 +550,9 @@ xrdp_codec_jpeg_compress(void *handle,
int cy, /* height of area to compress */
int quality, /* higher numbers compress less */
char *out_data, /* dest for jpg image */
- int *io_len /* length of out_data and on return */
- /* len of compressed data */
- );
+ int *io_len /* length of out_data and on return
+ len of compressed data */
+ );
void *
xrdp_jpeg_init(void);
@@ -559,7 +560,7 @@ int
xrdp_jpeg_deinit(void *handle);
/* xrdp_channel.c */
-struct xrdp_channel*
+struct xrdp_channel *
xrdp_channel_create(struct xrdp_sec *owner, struct xrdp_mcs *mcs_layer);
void
xrdp_channel_delete(struct xrdp_channel *self);
diff --git a/libxrdp/xrdp_caps.c b/libxrdp/xrdp_caps.c
index 1994966e..567f3ceb 100644
--- a/libxrdp/xrdp_caps.c
+++ b/libxrdp/xrdp_caps.c
@@ -77,7 +77,8 @@ xrdp_caps_process_general(struct xrdp_rdp *self, struct stream *s,
if (len < 10 + 2)
{
- LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_general: error");
+ LOG(LOG_LEVEL_ERROR, "Not enough bytes in the stream: "
+ "len 12, remaining %d", len);
return 1;
}
@@ -103,6 +104,9 @@ xrdp_caps_process_general(struct xrdp_rdp *self, struct stream *s,
}
/*****************************************************************************/
+/*
+ * Process [MS-RDPBCGR] TS_ORDER_CAPABILITYSET (2.2.7.1.3) message.
+ */
static int
xrdp_caps_process_order(struct xrdp_rdp *self, struct stream *s,
int len)
@@ -112,10 +116,10 @@ xrdp_caps_process_order(struct xrdp_rdp *self, struct stream *s,
int ex_flags;
int cap_flags;
- LOG_DEVEL(LOG_LEVEL_TRACE, "order capabilities");
if (len < 20 + 2 + 2 + 2 + 2 + 2 + 2 + 32 + 2 + 2 + 4 + 4 + 4 + 4)
{
- LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_order: error");
+ LOG(LOG_LEVEL_ERROR, "Not enough bytes in the stream: "
+ "len 84, remaining %d", len);
return 1;
}
in_uint8s(s, 20); /* Terminal desc, pad */
@@ -127,33 +131,53 @@ xrdp_caps_process_order(struct xrdp_rdp *self, struct stream *s,
in_uint16_le(s, cap_flags); /* Capability flags */
in_uint8a(s, order_caps, 32); /* Orders supported */
g_memcpy(self->client_info.orders, order_caps, 32);
- LOG_DEVEL(LOG_LEVEL_TRACE, "dest blt-0 %d", order_caps[0]);
- LOG_DEVEL(LOG_LEVEL_TRACE, "pat blt-1 %d", order_caps[1]);
- LOG_DEVEL(LOG_LEVEL_TRACE, "screen blt-2 %d", order_caps[2]);
- LOG_DEVEL(LOG_LEVEL_TRACE, "memblt-3-13 %d %d", order_caps[3], order_caps[13]);
- LOG_DEVEL(LOG_LEVEL_TRACE, "triblt-4-14 %d %d", order_caps[4], order_caps[14]);
- LOG_DEVEL(LOG_LEVEL_TRACE, "line-8 %d", order_caps[8]);
- LOG_DEVEL(LOG_LEVEL_TRACE, "line-9 %d", order_caps[9]);
- LOG_DEVEL(LOG_LEVEL_TRACE, "rect-10 %d", order_caps[10]);
- LOG_DEVEL(LOG_LEVEL_TRACE, "desksave-11 %d", order_caps[11]);
- LOG_DEVEL(LOG_LEVEL_TRACE, "polygon-20 %d", order_caps[20]);
- LOG_DEVEL(LOG_LEVEL_TRACE, "polygon2-21 %d", order_caps[21]);
- LOG_DEVEL(LOG_LEVEL_TRACE, "polyline-22 %d", order_caps[22]);
- LOG_DEVEL(LOG_LEVEL_TRACE, "ellipse-25 %d", order_caps[25]);
- LOG_DEVEL(LOG_LEVEL_TRACE, "ellipse2-26 %d", order_caps[26]);
- LOG_DEVEL(LOG_LEVEL_TRACE, "text2-27 %d", order_caps[27]);
- LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "order_caps dump", order_caps, 32);
+
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: terminalDescriptor (ignored as per protocol spec)");
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: desktopSaveXGranularity (ignored as per protocol spec)");
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: desktopSaveYGranularity (ignored as per protocol spec)");
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: maximumOrderLevel (ignored as per protocol spec)");
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: numberFonts (ignored as per protocol spec)");
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: orderFlags 0x%4.4x", cap_flags);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: orderSupport index 0: DstBlt %d", order_caps[0]);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: orderSupport index 1: PatBlt %d", order_caps[1]);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: orderSupport index 2: ScrBlt %d", order_caps[2]);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: orderSupport index 3,13: MemBlt %d %d", order_caps[3], order_caps[13]);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: orderSupport index 4,14: Mem3Blt %d %d", order_caps[4], order_caps[14]);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: orderSupport index 5-6: unused index");
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: orderSupport index 7: DrawNineGrid %d", order_caps[7]);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: orderSupport index 8: LineTo %d", order_caps[8]);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: orderSupport index 9: MultiDrawNineGrid %d", order_caps[9]);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: orderSupport index 10: unused index");
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: orderSupport index 11: SaveBitmap %d", order_caps[11]);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: orderSupport index 12-14: unused index");
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: orderSupport index 15: MultiDstBlt %d", order_caps[15]);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: orderSupport index 16: MultiPatBlt %d", order_caps[16]);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: orderSupport index 17: MultiScrBlt %d", order_caps[17]);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: orderSupport index 18: MultiOpaqueRect %d", order_caps[18]);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: orderSupport index 19: FastIndex %d", order_caps[19]);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: orderSupport index 20: PolygonSC %d", order_caps[20]);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: orderSupport index 21: PolygonCB %d", order_caps[21]);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: orderSupport index 22: Polyline %d", order_caps[22]);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: orderSupport index 23: unused index");
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: orderSupport index 24: FastGlyph %d", order_caps[24]);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: orderSupport index 25: EllipseSC %d", order_caps[25]);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: orderSupport index 26: EllipseCB %d", order_caps[26]);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: orderSupport index 27: GlyphIndex %d", order_caps[27]);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: orderSupport index 28-31: unused index");
+ LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: order_caps", order_caps, 32);
in_uint8s(s, 2); /* Text capability flags */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: textFlags (ignored as per protocol spec)");
/* read extended order support flags */
in_uint16_le(s, ex_flags); /* Ex flags */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: orderSupportExFlags 0x%4.4x", ex_flags);
if (cap_flags & 0x80) /* ORDER_FLAGS_EXTRA_SUPPORT */
{
self->client_info.order_flags_ex = ex_flags;
if (ex_flags & XR_ORDERFLAGS_EX_CACHE_BITMAP_REV3_SUPPORT)
{
- LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_process_order: bitmap cache v3 supported");
+ LOG_DEVEL(LOG_LEVEL_INFO, "Client Capability: bitmap cache v3 supported");
self->client_info.bitmap_cache_version |= 4;
}
}
@@ -161,15 +185,15 @@ xrdp_caps_process_order(struct xrdp_rdp *self, struct stream *s,
in_uint32_le(s, i); /* desktop cache size, usually 0x38400 */
self->client_info.desktop_cache = i;
- LOG_DEVEL(LOG_LEVEL_TRACE, "desktop cache size %d", i);
- in_uint8s(s, 4); /* Unknown */
- in_uint8s(s, 4); /* Unknown */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "TS_ORDER_CAPABILITYSET: desktopSaveSize %d", i);
+ in_uint8s(s, 4); /* Pad */
+ in_uint8s(s, 4); /* Pad */
/* check if libpainter should be used for drawing, instead of orders */
if (!(order_caps[TS_NEG_DSTBLT_INDEX] && order_caps[TS_NEG_PATBLT_INDEX] &&
order_caps[TS_NEG_SCRBLT_INDEX] && order_caps[TS_NEG_MEMBLT_INDEX]))
{
- LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_process_order: not enough orders supported by client, using painter.");
+ LOG_DEVEL(LOG_LEVEL_INFO, "Client Capability: not enough orders supported by client, using painter.");
self->client_info.no_orders_supported = 1;
}
@@ -186,7 +210,8 @@ xrdp_caps_process_bmpcache(struct xrdp_rdp *self, struct stream *s,
if (len < 24 + 2 + 2 + 2 + 2 + 2 + 2)
{
- LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_bmpcache: error");
+ LOG(LOG_LEVEL_ERROR, "Not enough bytes in the stream: "
+ "len 36, remaining %d", len);
return 1;
}
self->client_info.bitmap_cache_version |= 1;
@@ -229,7 +254,8 @@ xrdp_caps_process_bmpcache2(struct xrdp_rdp *self, struct stream *s,
if (len < 2 + 2 + 4 + 4 + 4)
{
- LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_bmpcache2: error");
+ LOG(LOG_LEVEL_ERROR, "Not enough bytes in the stream: "
+ "len 16, remaining %d", len);
return 1;
}
self->client_info.bitmap_cache_version |= 2;
@@ -271,7 +297,8 @@ xrdp_caps_process_cache_v3_codec_id(struct xrdp_rdp *self, struct stream *s,
if (len < 1)
{
- LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_cache_v3_codec_id: error");
+ LOG(LOG_LEVEL_ERROR, "Not enough bytes in the stream: "
+ "len 1, remaining %d", len);
return 1;
}
in_uint8(s, codec_id);
@@ -421,13 +448,24 @@ xrdp_caps_process_rail(struct xrdp_rdp *self, struct stream *s, int len)
if (len < 4)
{
- LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_rail: error");
+ LOG(LOG_LEVEL_ERROR, "Not enough bytes in the stream: "
+ "len 4, remaining %d", len);
return 1;
}
in_uint32_le(s, i32);
self->client_info.rail_support_level = i32;
- LOG(LOG_LEVEL_INFO, "xrdp_process_capset_rail: rail_support_level %d",
- self->client_info.rail_support_level);
+ LOG(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - CAPSTYPE_RAIL "
+ "RailSupportLevel 0x%8.8x (%s%s%s%s%s%s%s%s)",
+ self->client_info.rail_support_level,
+ (self->client_info.rail_support_level & 0x01) ? "TS_RAIL_LEVEL_SUPPORTED " : "",
+ (self->client_info.rail_support_level & 0x02) ? "TS_RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED " : "",
+ (self->client_info.rail_support_level & 0x04) ? "TS_RAIL_LEVEL_SHELL_INTEGRATION_SUPPORTED " : "",
+ (self->client_info.rail_support_level & 0x08) ? "TS_RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED " : "",
+ (self->client_info.rail_support_level & 0x10) ? "TS_RAIL_LEVEL_SERVER_TO_CLIENT_IME_SYNC_SUPPORTED " : "",
+ (self->client_info.rail_support_level & 0x20) ? "TS_RAIL_LEVEL_HIDE_MINIMIZED_APPS_SUPPORTED " : "",
+ (self->client_info.rail_support_level & 0x40) ? "TS_RAIL_LEVEL_WINDOW_CLOAKING_SUPPORTED " : "",
+ (self->client_info.rail_support_level & 0x80) ? "TS_RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED " : ""
+ );
return 0;
}
@@ -448,8 +486,8 @@ xrdp_caps_process_window(struct xrdp_rdp *self, struct stream *s, int len)
self->client_info.wnd_num_icon_caches = i32;
in_uint16_le(s, i32);
self->client_info.wnd_num_icon_cache_entries = i32;
- LOG(LOG_LEVEL_INFO, "xrdp_process_capset_window wnd_support_level %d "
- "wnd_num_icon_caches %d wnd_num_icon_cache_entries %d",
+ LOG(LOG_LEVEL_INFO, "xrdp_process_capset_window wnd_support_level %d, "
+ "wnd_num_icon_caches %d, wnd_num_icon_cache_entries %d",
self->client_info.wnd_support_level,
self->client_info.wnd_num_icon_caches,
self->client_info.wnd_num_icon_cache_entries);
@@ -593,6 +631,7 @@ xrdp_caps_process_surface_cmds(struct xrdp_rdp *self, struct stream *s, int len)
logging in debug mode */
UNUSED_VAR(cmdFlags);
#endif
+
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_process_surface_cmds:");
in_uint32_le(s, cmdFlags);
in_uint8s(s, 4); /* reserved */
@@ -601,6 +640,9 @@ xrdp_caps_process_surface_cmds(struct xrdp_rdp *self, struct stream *s, int len)
}
/*****************************************************************************/
+/*
+ * Process a [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU (2.2.1.13.2.1) message.
+ */
int
xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
{
@@ -612,7 +654,6 @@ xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
int len;
char *p;
- LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_caps_process_confirm_active");
in_uint8s(s, 4); /* rdp_shareid */
in_uint8s(s, 2); /* userid */
in_uint16_le(s, source_len); /* sizeof RDP_SOURCE */
@@ -620,118 +661,169 @@ xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
in_uint8s(s, source_len);
in_uint16_le(s, num_caps);
in_uint8s(s, 2); /* pad */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU "
+ "shareID (ignored), originatorID (ignored), lengthSourceDescriptor %d, "
+ "lengthCombinedCapabilities %d, sourceDescriptor (ignored), "
+ "numberCapabilities %d", source_len, cap_len, num_caps);
if ((cap_len < 0) || (cap_len > 1024 * 1024))
{
+ LOG(LOG_LEVEL_ERROR, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU "
+ "lengthCombinedCapabilities %d is too long (> %d)",
+ cap_len, 1024 * 1024);
return 1;
}
for (index = 0; index < num_caps; index++)
{
p = s->p;
- if (!s_check_rem(s, 4))
+ if (!s_check_rem_and_log(s, 4,
+ "Parsing [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET"))
{
- LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_confirm_active: error 1");
return 1;
}
in_uint16_le(s, type);
in_uint16_le(s, len);
- if ((len < 4) || !s_check_rem(s, len - 4))
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "
+ "capabilitySetType %d, lengthCapability %d", type, len);
+ if (len < 4)
+ {
+ LOG(LOG_LEVEL_ERROR,
+ "Protocol error [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "
+ "lengthCapability must be greater than 3, received %d", len);
+ return 1;
+ }
+ if (!s_check_rem_and_log(s, len - 4,
+ "Parsing [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "))
{
- LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_confirm_active: error: len %d, "
- "remaining %d", len, (int) (s->end - s->p));
return 1;
}
len -= 4;
switch (type)
{
case CAPSTYPE_GENERAL:
- LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_GENERAL");
+ LOG_DEVEL(LOG_LEVEL_INFO, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "
+ "capabilitySetType = CAPSTYPE_GENERAL");
xrdp_caps_process_general(self, s, len);
break;
case CAPSTYPE_BITMAP:
- LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_BITMAP");
+ LOG_DEVEL(LOG_LEVEL_INFO, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "
+ "capabilitySetType = CAPSTYPE_BITMAP - Ignored");
break;
case CAPSTYPE_ORDER:
- LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_ORDER");
+ LOG_DEVEL(LOG_LEVEL_INFO, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "
+ "capabilitySetType = CAPSTYPE_ORDER");
xrdp_caps_process_order(self, s, len);
break;
case CAPSTYPE_BITMAPCACHE:
- LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_BMPCACHE");
+ LOG_DEVEL(LOG_LEVEL_INFO, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "
+ "capabilitySetType = CAPSTYPE_BITMAPCACHE");
xrdp_caps_process_bmpcache(self, s, len);
break;
case CAPSTYPE_CONTROL:
- LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_CONTROL");
+ LOG_DEVEL(LOG_LEVEL_INFO, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "
+ "capabilitySetType = CAPSTYPE_CONTROL - Ignored");
break;
case 6:
+ LOG_DEVEL(LOG_LEVEL_INFO, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "
+ "capabilitySetType = 6");
xrdp_caps_process_cache_v3_codec_id(self, s, len);
break;
case CAPSTYPE_ACTIVATION:
- LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_ACTIVAION");
+ LOG_DEVEL(LOG_LEVEL_INFO, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "
+ "capabilitySetType = CAPSTYPE_ACTIVATION - Ignored");
break;
case CAPSTYPE_POINTER:
- LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_POINTER");
+ LOG_DEVEL(LOG_LEVEL_INFO, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "
+ "capabilitySetType = CAPSTYPE_POINTER");
xrdp_caps_process_pointer(self, s, len);
break;
case CAPSTYPE_SHARE:
- LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_SHARE");
+ LOG_DEVEL(LOG_LEVEL_INFO, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "
+ "capabilitySetType = CAPSTYPE_SHARE - Ignored");
break;
case CAPSTYPE_COLORCACHE:
- LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_COLORCACHE");
+ LOG_DEVEL(LOG_LEVEL_INFO, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "
+ "capabilitySetType = CAPSTYPE_COLORCACHE - Ignored");
break;
case CAPSTYPE_SOUND:
- LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_SOUND");
+ LOG_DEVEL(LOG_LEVEL_INFO, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "
+ "capabilitySetType = CAPSTYPE_SOUND - Ignored");
break;
case CAPSTYPE_INPUT:
+ LOG_DEVEL(LOG_LEVEL_INFO, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "
+ "capabilitySetType = CAPSTYPE_INPUT");
xrdp_caps_process_input(self, s, len);
break;
case CAPSTYPE_FONT:
- LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_FONT");
+ LOG_DEVEL(LOG_LEVEL_INFO, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "
+ "capabilitySetType = CAPSTYPE_FONT - Ignored");
break;
case CAPSTYPE_BRUSH:
+ LOG_DEVEL(LOG_LEVEL_INFO, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "
+ "capabilitySetType = CAPSTYPE_BRUSH");
xrdp_caps_process_brushcache(self, s, len);
break;
case CAPSTYPE_GLYPHCACHE:
- LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_GLYPHCACHE");
+ LOG_DEVEL(LOG_LEVEL_INFO, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "
+ "capabilitySetType = CAPSTYPE_GLYPHCACHE");
xrdp_caps_process_glyphcache(self, s, len);
break;
case CAPSTYPE_OFFSCREENCACHE:
- LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_OFFSCREENCACHE");
+ LOG_DEVEL(LOG_LEVEL_INFO, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "
+ "capabilitySetType = CAPSTYPE_OFFSCREENCACHE");
xrdp_caps_process_offscreen_bmpcache(self, s, len);
break;
case CAPSTYPE_BITMAPCACHE_REV2:
- LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_BITMAPCACHE_REV2");
+ LOG_DEVEL(LOG_LEVEL_INFO, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "
+ "capabilitySetType = CAPSTYPE_BITMAPCACHE_REV2");
xrdp_caps_process_bmpcache2(self, s, len);
break;
case CAPSTYPE_VIRTUALCHANNEL:
- LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_VIRTUALCHANNEL");
+ LOG_DEVEL(LOG_LEVEL_INFO, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "
+ "capabilitySetType = CAPSTYPE_VIRTUALCHANNEL - Ignored");
break;
case CAPSTYPE_DRAWNINGRIDCACHE:
- LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_DRAWNINGRIDCACHE");
+ LOG_DEVEL(LOG_LEVEL_INFO, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "
+ "capabilitySetType = CAPSTYPE_DRAWNINGRIDCACHE - Ignored");
break;
case CAPSTYPE_DRAWGDIPLUS:
- LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_DRAWGDIPLUS");
+ LOG_DEVEL(LOG_LEVEL_INFO, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "
+ "capabilitySetType = CAPSTYPE_DRAWGDIPLUS - Ignored");
break;
case CAPSTYPE_RAIL:
+ LOG_DEVEL(LOG_LEVEL_INFO, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "
+ "capabilitySetType = CAPSTYPE_RAIL");
xrdp_caps_process_rail(self, s, len);
break;
case CAPSTYPE_WINDOW:
+ LOG_DEVEL(LOG_LEVEL_INFO, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "
+ "capabilitySetType = CAPSTYPE_WINDOW");
xrdp_caps_process_window(self, s, len);
break;
case CAPSSETTYPE_MULTIFRAGMENTUPDATE:
+ LOG_DEVEL(LOG_LEVEL_INFO, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "
+ "capabilitySetType = CAPSSETTYPE_MULTIFRAGMENTUPDATE");
xrdp_caps_process_multifragmentupdate(self, s, len);
break;
case CAPSETTYPE_SURFACE_COMMANDS:
+ LOG_DEVEL(LOG_LEVEL_INFO, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "
+ "capabilitySetType = CAPSETTYPE_SURFACE_COMMANDS");
xrdp_caps_process_surface_cmds(self, s, len);
break;
case CAPSSETTYPE_BITMAP_CODECS:
+ LOG_DEVEL(LOG_LEVEL_INFO, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "
+ "capabilitySetType = CAPSSETTYPE_BITMAP_CODECS");
xrdp_caps_process_codecs(self, s, len);
break;
case CAPSTYPE_FRAME_ACKNOWLEDGE:
+ LOG_DEVEL(LOG_LEVEL_INFO, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "
+ "capabilitySetType = CAPSTYPE_FRAME_ACKNOWLEDGE");
xrdp_caps_process_frame_ack(self, s, len);
break;
default:
- LOG(LOG_LEVEL_WARNING, "unknown in xrdp_caps_process_confirm_active %d", type);
+ LOG(LOG_LEVEL_WARNING, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "
+ "capabilitySetType = %d is unknown - Ignored", type);
break;
}
@@ -741,7 +833,7 @@ xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
if (self->client_info.no_orders_supported &&
(self->client_info.offscreen_support_level != 0))
{
- LOG(LOG_LEVEL_WARNING, "xrdp_caps_process_confirm_active: not enough orders "
+ LOG(LOG_LEVEL_WARNING, "Client Capability: not enough orders "
"supported by client, client wants off screen bitmap but "
"offscreen bitmaps disabled");
self->client_info.offscreen_support_level = 0;
@@ -749,7 +841,7 @@ xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
self->client_info.offscreen_cache_entries = 0;
}
- LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_caps_process_confirm_active");
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Completed processing received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU");
return 0;
}
/*****************************************************************************/
@@ -771,10 +863,10 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
make_stream(s);
init_stream(s, 8192);
- LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_caps_send_demand_active");
if (xrdp_rdp_init(self, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "xrdp_caps_send_demand_active: xrdp_rdp_init failed");
free_stream(s);
return 1;
}
@@ -797,6 +889,9 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
out_uint16_le(s, CAPSTYPE_SHARE_LEN);
out_uint16_le(s, self->mcs_channel);
out_uint16_be(s, 0xb5e2); /* 0x73e1 */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_send_demand_active: Server Capability "
+ "CAPSTYPE_SHARE "
+ "channel ID = 0x%x", self->mcs_channel);
/* Output general capability set */
caps_count++;
@@ -820,6 +915,8 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
out_uint16_le(s, 0); /* Compression level */
out_uint8(s, 1); /* refreshRectSupport */
out_uint8(s, 1); /* suppressOutputSupport */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_send_demand_active: Server Capability "
+ "CAPSTYPE_GENERAL TODO");
/* Output bitmap capability set */
caps_count++;
@@ -837,11 +934,15 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
out_uint16_le(s, 0); /* unknown */
out_uint16_le(s, 0); /* unknown */
out_uint16_le(s, 0); /* pad */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_send_demand_active: Server Capability "
+ "CAPSTYPE_BITMAP TODO");
/* Output font capability set */
caps_count++;
out_uint16_le(s, CAPSTYPE_FONT);
out_uint16_le(s, CAPSTYPE_FONT_LEN);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_send_demand_active: Server Capability "
+ "CAPSTYPE_FONT");
/* Output order capability set */
caps_count++;
@@ -895,6 +996,9 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
out_uint32_le(s, 0x0f4240); /* desk save */
out_uint32_le(s, 1); /* ? */
out_uint32_le(s, 0); /* ? */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_send_demand_active: Server Capability "
+ "CAPSTYPE_ORDER "
+ "TODO");
/* Output bmpcodecs capability set */
caps_count++;
@@ -912,6 +1016,11 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
out_uint8(s, 0x01); /* fAllowDynamicFidelity */
out_uint8(s, 0x01); /* fAllowSubsampling */
out_uint8(s, 0x03); /* colorLossLevel */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_send_demand_active: Server Capability "
+ "NSCODEC "
+ "fAllowDynamicFidelity = 0x01,"
+ "fAllowSubsampling = 0x01,"
+ "colorLossLevel = 0x03");
#if defined(XRDP_RFXCODEC) || defined(XRDP_NEUTRINORDP)
/* remotefx */
codec_caps_count++;
@@ -919,12 +1028,16 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
out_uint8(s, 0); /* codec id, client sets */
out_uint16_le(s, 4); /* codecPropertiesLength */
out_uint32_le(s, 0); /* reserved */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_send_demand_active: Server Capability "
+ "REMOTEFX");
/* image remotefx */
codec_caps_count++;
out_uint8a(s, XR_CODEC_GUID_IMAGE_REMOTEFX, 16);
out_uint8(s, 0); /* codec id, client sets */
out_uint16_le(s, 4); /* codecPropertiesLength */
out_uint32_le(s, 0); /* reserved */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_send_demand_active: Server Capability "
+ "IMAGE_REMOTEFX");
#endif
/* jpeg */
codec_caps_count++;
@@ -932,6 +1045,9 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
out_uint8(s, 0); /* codec id, client sets */
out_uint16_le(s, 1); /* codecPropertiesLength */
out_uint8(s, 75); /* jpeg compression ratio */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_send_demand_active: Server Capability "
+ "JPEG: "
+ "jpeg compression ratio = 75");
/* calculate and set size and count */
codec_caps_size = (int)(s->p - codec_caps_size_ptr);
codec_caps_size += 2; /* 2 bytes for CAPSTYPE_BMPCODECS above */
@@ -945,6 +1061,9 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
out_uint16_le(s, CAPSTYPE_COLORCACHE_LEN);
out_uint16_le(s, 6); /* cache size */
out_uint16_le(s, 0); /* pad */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_send_demand_active: Server Capability "
+ "CAPSTYPE_COLORCACHE: "
+ "colorTableCacheSize = 6");
/* Output pointer capability set */
caps_count++;
@@ -953,8 +1072,14 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
out_uint16_le(s, 1); /* Colour pointer */
out_uint16_le(s, 0x19); /* Cache size */
out_uint16_le(s, 0x19); /* Cache size */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_send_demand_active: Server Capability "
+ "CAPSTYPE_POINTER: "
+ "colorPointerFlag = true"
+ "colorPointerCacheSize = 0x19"
+ "pointerCacheSize = 0x19");
/* Output input capability set */
+ /* https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/b3bc76ae-9ee5-454f-b197-ede845ca69cc */
caps_count++;
out_uint16_le(s, CAPSTYPE_INPUT);
out_uint16_le(s, CAPSTYPE_INPUT_LEN);
@@ -970,6 +1095,9 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
}
out_uint16_le(s, flags);
out_uint8s(s, 82);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_send_demand_active: Server Capability "
+ "CAPSTYPE_INPUT: "
+ "inputFlags = 0x%x", flags);
if (self->client_info.rail_enable) /* MS-RDPERP 3.3.5.1.4 */
{
@@ -980,6 +1108,10 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
out_uint32_le(s, 3); /* See: https://msdn.microsoft.com/en-us/library/cc242518.aspx
TS_RAIL_LEVEL_SUPPORTED
TS_RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_send_demand_active: Server Capability "
+ "CAPSTYPE_RAIL: "
+ "RailSupportLevel = "
+ "TS_RAIL_LEVEL_SUPPORTED | TS_RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED");
/* Window List Capability Set */
caps_count++;
@@ -988,6 +1120,11 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
out_uint32_le(s, TS_WINDOW_LEVEL_SUPPORTED_EX);
out_uint8(s, 3); /* NumIconCaches */
out_uint16_le(s, 12); /* NumIconCacheEntries */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_send_demand_active: Server Capability "
+ "CAPSTYPE_WINDOW: "
+ "WndSupportLevel = TS_WINDOW_LEVEL_SUPPORTED_EX, "
+ "NumIconCaches = 3,"
+ "NumIconCacheEntries = 12");
}
/* 6 - bitmap cache v3 codecid */
@@ -995,6 +1132,8 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
out_uint16_le(s, 0x0006);
out_uint16_le(s, 5);
out_uint8(s, 0); /* client sets */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_send_demand_active: Server Capability "
+ "0x0006 = 0");
if (self->client_info.use_fast_path & FASTPATH_OUTPUT_SUPPORTED) /* fastpath output on */
{
@@ -1003,12 +1142,16 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
out_uint16_le(s, CAPSSETTYPE_MULTIFRAGMENTUPDATE);
out_uint16_le(s, CAPSSETTYPE_MULTIFRAGMENTUPDATE_LEN);
out_uint32_le(s, 3 * 1024 * 1024); /* 3MB */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_send_demand_active: Server Capability "
+ "CAPSSETTYPE_MULTIFRAGMENTUPDATE = 3MB");
/* frame acks */
caps_count++;
out_uint16_le(s, CAPSTYPE_FRAME_ACKNOWLEDGE);
out_uint16_le(s, CAPSTYPE_FRAME_ACKNOWLEDGE_LEN);
out_uint32_le(s, 2); /* 2 frames in flight */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_send_demand_active: Server Capability "
+ "CAPSTYPE_FRAME_ACKNOWLEDGE = 2 frames");
/* surface commands */
caps_count++;
@@ -1018,6 +1161,9 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
SURFCMDS_FRAMEMARKER |
SURFCMDS_STREAMSUFRACEBITS)); /* cmdFlags */
out_uint32_le(s, 0); /* reserved */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_send_demand_active: Server Capability "
+ "CAPSETTYPE_SURFACE_COMMANDS = "
+ "SURFCMDS_SETSURFACEBITS | SURFCMDS_FRAMEMARKER | SURFCMDS_STREAMSUFRACEBITS");
}
out_uint8s(s, 4); /* pad */
@@ -1033,12 +1179,14 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
caps_count_ptr[2] = caps_count >> 16;
caps_count_ptr[3] = caps_count >> 24;
+ LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_send_demand_active: sending PDUTYPE_DEMANDACTIVEPDU "
+ "message with the server's capabilities");
if (xrdp_rdp_send(self, s, PDUTYPE_DEMANDACTIVEPDU) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "xrdp_caps_send_demand_active: xrdp_rdp_send failed");
free_stream(s);
return 1;
}
- LOG_DEVEL(LOG_LEVEL_TRACE, "out (1) xrdp_caps_send_demand_active");
/* send Monitor Layout PDU for dual monitor */
if (self->client_info.monitorCount > 0 &&
diff --git a/libxrdp/xrdp_channel.c b/libxrdp/xrdp_channel.c
index 5f506548..9a374cac 100644
--- a/libxrdp/xrdp_channel.c
+++ b/libxrdp/xrdp_channel.c
@@ -43,6 +43,19 @@
#define XRDP_DRDYNVC_STATUS_OPEN 2
#define XRDP_DRDYNVC_STATUS_CLOSE_SENT 3
+#define XRDP_DRDYNVC_STATUS_TO_STR(status) \
+ ((status) == XRDP_DRDYNVC_STATUS_CLOSED ? "CLOSED" : \
+ (status) == XRDP_DRDYNVC_STATUS_OPEN_SENT ? "OPEN_SENT" : \
+ (status) == XRDP_DRDYNVC_STATUS_OPEN ? "OPEN" : \
+ (status) == XRDP_DRDYNVC_STATUS_CLOSE_SENT ? "CLOSE_SENT" : \
+ "unknown" \
+ )
+
+#define XRDP_DRDYNVC_CHANNEL_ID_TO_NAME(self, chan_id) \
+ (xrdp_channel_get_item((self), (chan_id)) != NULL \
+ ? xrdp_channel_get_item((self), (chan_id))->name \
+ : "unknown")
+
/*****************************************************************************/
/* returns pointer or nil on error */
static struct mcs_channel_item *
@@ -52,7 +65,7 @@ xrdp_channel_get_item(struct xrdp_channel *self, int channel_id)
if (self->mcs_layer->channel_list == NULL)
{
- LOG(LOG_LEVEL_ERROR, "xrdp_channel_get_item - No channel initialized");
+ LOG(LOG_LEVEL_WARNING, "Channel list is NULL, returning NULL");
return NULL ;
}
@@ -95,6 +108,7 @@ xrdp_channel_init(struct xrdp_channel *self, struct stream *s)
{
if (xrdp_sec_init(self->sec_layer, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "xrdp_channel_init: xrdp_sec_init failed");
return 1;
}
@@ -115,13 +129,17 @@ xrdp_channel_send(struct xrdp_channel *self, struct stream *s, int channel_id,
if (channel == NULL)
{
- LOG(LOG_LEVEL_ERROR, "xrdp_channel_send - no such channel");
+ LOG(LOG_LEVEL_ERROR,
+ "Request to send a message to non-existent channel_id %d",
+ channel_id);
return 1;
}
if (channel->disabled)
{
- LOG(LOG_LEVEL_WARNING, "xrdp_channel_send, channel disabled");
+ LOG(LOG_LEVEL_DEBUG,
+ "Request to send a message to the disabled channel %s (%d)",
+ channel->name, channel_id);
return 0; /* not an error */
}
@@ -145,10 +163,12 @@ xrdp_channel_send(struct xrdp_channel *self, struct stream *s, int channel_id,
// }
out_uint32_le(s, flags);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPBCGR] CHANNEL_PDU_HEADER "
+ "length %d, flags 0x%8.8x", total_data_len, flags);
if (xrdp_sec_send(self->sec_layer, s, channel->chanid) != 0)
{
- LOG(LOG_LEVEL_ERROR, "xrdp_channel_send - failure sending data");
+ LOG(LOG_LEVEL_ERROR, "xrdp_channel_send: xrdp_sec_send failed");
return 1;
}
@@ -183,18 +203,28 @@ xrdp_channel_call_callback(struct xrdp_channel *self, struct stream *s,
}
else
{
- LOG(LOG_LEVEL_TRACE, "in xrdp_channel_call_callback, session->callback is nil");
+ LOG_DEVEL(LOG_LEVEL_WARNING, "session->callback is NULL");
}
}
else
{
- LOG(LOG_LEVEL_TRACE, "in xrdp_channel_call_callback, session is nil");
+ LOG_DEVEL(LOG_LEVEL_WARNING, "session is NULL");
}
return rv;
}
/*****************************************************************************/
+/**
+ * Write a variable length unsigned int (1, 2, or 4 bytes) to the stream.
+ *
+ * The number of bytes written is the minimum number of bytes needed to
+ * represent the value.
+ *
+ * @param s the stream to write to
+ * @param val the value to write
+ * @return the DYNVC cbId length code for the number of bytes written (see [MS-RDPEDYC] 2.2.2.1)
+ */
static int
drdynvc_insert_uint_124(struct stream *s, uint32_t val)
{
@@ -220,6 +250,17 @@ drdynvc_insert_uint_124(struct stream *s, uint32_t val)
}
/*****************************************************************************/
+/**
+ * Read a variable length unsigned int (1, 2, or 4 bytes) from the stream.
+ *
+ * The number of bytes read is determined by the cbId bit field flag in the
+ * cmd argument (see [MS-RDPEDYC] 2.2.2.1).
+ *
+ * @param s [in] the stream to read from
+ * @param cmd [in] the cmd byte which contains the cbId bit field flag
+ * @param chan_id_p [out] a pointer to the value read from the stream
+ * @return error code
+ */
static int
drdynvc_get_chan_id(struct stream *s, char cmd, uint32_t *chan_id_p)
{
@@ -229,7 +270,7 @@ drdynvc_get_chan_id(struct stream *s, char cmd, uint32_t *chan_id_p)
cbChId = cmd & 0x03;
if (cbChId == 0)
{
- if (!s_check_rem(s, 1))
+ if (!s_check_rem_and_log(s, 1, "Parsing [MS-RDPEDYC] channel id"))
{
return 1;
}
@@ -237,7 +278,7 @@ drdynvc_get_chan_id(struct stream *s, char cmd, uint32_t *chan_id_p)
}
else if (cbChId == 1)
{
- if (!s_check_rem(s, 2))
+ if (!s_check_rem_and_log(s, 2, "Parsing [MS-RDPEDYC] channel id"))
{
return 1;
}
@@ -245,7 +286,7 @@ drdynvc_get_chan_id(struct stream *s, char cmd, uint32_t *chan_id_p)
}
else
{
- if (!s_check_rem(s, 4))
+ if (!s_check_rem_and_log(s, 4, "Parsing [MS-RDPEDYC] channel id"))
{
return 1;
}
@@ -256,6 +297,9 @@ drdynvc_get_chan_id(struct stream *s, char cmd, uint32_t *chan_id_p)
}
/*****************************************************************************/
+/*
+ * Process a [MS-RDPEDYC] DYNVC_CAPS_RSP message.
+ */
static int
drdynvc_process_capability_response(struct xrdp_channel *self,
int cmd, struct stream *s)
@@ -264,18 +308,22 @@ drdynvc_process_capability_response(struct xrdp_channel *self,
int cap_version;
int rv;
- /* skip padding */
- in_uint8s(s, 1);
- /* read client's version */
- in_uint16_le(s, cap_version);
+ if (!s_check_rem_and_log(s, 3, "Parsing [MS-RDPEDYC] DYNVC_CAPS_RSP"))
+ {
+ return 1;
+ }
+ in_uint8s(s, 1); /* skip padding */
+ in_uint16_le(s, cap_version); /* Version */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPEDYC] DYNVC_CAPS_RSP "
+ "version %d", cap_version);
+
if ((cap_version != 2) && (cap_version != 3))
{
- LOG(LOG_LEVEL_ERROR, "drdynvc_process_capability_response: incompatible DVC "
- "version %d detected", cap_version);
+ LOG(LOG_LEVEL_ERROR,
+ "Dynamic Virtual Channel version %d is not supported",
+ cap_version);
return 1;
}
- LOG(LOG_LEVEL_INFO, "drdynvc_process_capability_response: DVC version %d selected",
- cap_version);
self->drdynvc_state = 1;
session = self->sec_layer->rdp_layer->session;
rv = session->callback(session->id, 0x5558, 0, 0, 0, 0);
@@ -283,6 +331,9 @@ drdynvc_process_capability_response(struct xrdp_channel *self,
}
/*****************************************************************************/
+/*
+ * Process a [MS-RDPEDYC] DYNVC_CREATE_RSP message.
+ */
static int
drdynvc_process_open_channel_response(struct xrdp_channel *self,
int cmd, struct stream *s)
@@ -292,22 +343,27 @@ drdynvc_process_open_channel_response(struct xrdp_channel *self,
uint32_t chan_id;
struct xrdp_drdynvc *drdynvc;
- if (drdynvc_get_chan_id(s, cmd, &chan_id) != 0)
+ if (drdynvc_get_chan_id(s, cmd, &chan_id) != 0) /* ChannelId */
{
+ LOG(LOG_LEVEL_ERROR,
+ "Parsing [MS-RDPEDYC] DYNVC_CREATE_RSP failed");
return 1;
}
- if (!s_check_rem(s, 4))
+ if (!s_check_rem_and_log(s, 4, "Parsing [MS-RDPEDYC] DYNVC_CREATE_RSP"))
{
return 1;
}
- in_uint32_le(s, creation_status);
- LOG_DEVEL(LOG_LEVEL_TRACE, "drdynvc_process_open_channel_response: chan_id 0x%x "
- "creation_status %d", chan_id, creation_status);
- session = self->sec_layer->rdp_layer->session;
+ in_uint32_le(s, creation_status); /* CreationStatus */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPEDYC] DYNVC_CREATE_RSP "
+ "ChannelId %d, CreationStatus %d", chan_id, creation_status);
if (chan_id > 255)
{
+ LOG(LOG_LEVEL_ERROR, "Received [MS-RDPEDYC] DYNVC_CREATE_RSP for an "
+ "invalid channel id. Max allowed 255, received %d", chan_id);
return 1;
}
+
+ session = self->sec_layer->rdp_layer->session;
drdynvc = self->drdynvcs + chan_id;
if (creation_status == 0)
{
@@ -317,14 +373,26 @@ drdynvc_process_open_channel_response(struct xrdp_channel *self,
{
drdynvc->status = XRDP_DRDYNVC_STATUS_CLOSED;
}
+ LOG_DEVEL(LOG_LEVEL_DEBUG,
+ "Dynamic Virtual Channel %s (%d) updated: status = %s",
+ XRDP_DRDYNVC_CHANNEL_ID_TO_NAME(self, chan_id),
+ chan_id,
+ XRDP_DRDYNVC_STATUS_TO_STR(drdynvc->status));
if (drdynvc->open_response != NULL)
{
return drdynvc->open_response(session->id, chan_id, creation_status);
}
+ LOG_DEVEL(LOG_LEVEL_WARNING, "Dynamic Virtual Channel %s (%d): "
+ "callback 'open_response' is NULL",
+ XRDP_DRDYNVC_CHANNEL_ID_TO_NAME(self, chan_id),
+ chan_id);
return 0;
}
/*****************************************************************************/
+/*
+ * Process a [MS-RDPEDYC] DYNVC_CLOSE message.
+ */
static int
drdynvc_process_close_channel_response(struct xrdp_channel *self,
int cmd, struct stream *s)
@@ -333,26 +401,45 @@ drdynvc_process_close_channel_response(struct xrdp_channel *self,
uint32_t chan_id;
struct xrdp_drdynvc *drdynvc;
- if (drdynvc_get_chan_id(s, cmd, &chan_id) != 0)
+ if (drdynvc_get_chan_id(s, cmd, &chan_id) != 0) /* ChannelId */
{
+ LOG(LOG_LEVEL_ERROR,
+ "drdynvc_process_close_channel_response: drdynvc_get_chan_id failed");
return 1;
}
- LOG_DEVEL(LOG_LEVEL_TRACE, "drdynvc_process_close_channel_response: chan_id 0x%x", chan_id);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPEDYC] DYNVC_CLOSE "
+ "ChannelId %d", chan_id);
session = self->sec_layer->rdp_layer->session;
if (chan_id > 255)
{
+ LOG(LOG_LEVEL_ERROR, "Received message for an invalid "
+ "channel id. channel id %d", chan_id);
return 1;
}
+
drdynvc = self->drdynvcs + chan_id;
drdynvc->status = XRDP_DRDYNVC_STATUS_CLOSED;
+ LOG_DEVEL(LOG_LEVEL_DEBUG,
+ "Dynamic Virtual Channel %s (%d) updated: status = %s",
+ XRDP_DRDYNVC_CHANNEL_ID_TO_NAME(self, chan_id),
+ chan_id,
+ XRDP_DRDYNVC_STATUS_TO_STR(drdynvc->status));
+
if (drdynvc->close_response != NULL)
{
return drdynvc->close_response(session->id, chan_id);
}
+ LOG_DEVEL(LOG_LEVEL_WARNING, "Dynamic Virtual Channel %s (%d): "
+ "callback 'close_response' is NULL",
+ XRDP_DRDYNVC_CHANNEL_ID_TO_NAME(self, chan_id),
+ chan_id);
return 0;
}
/*****************************************************************************/
+/*
+ * Process a [MS-RDPEDYC] DYNVC_DATA_FIRST message.
+ */
static int
drdynvc_process_data_first(struct xrdp_channel *self,
int cmd, struct stream *s)
@@ -364,40 +451,47 @@ drdynvc_process_data_first(struct xrdp_channel *self,
int total_bytes;
struct xrdp_drdynvc *drdynvc;
- if (drdynvc_get_chan_id(s, cmd, &chan_id) != 0)
+ if (drdynvc_get_chan_id(s, cmd, &chan_id) != 0) /* ChannelId */
{
+ LOG(LOG_LEVEL_ERROR,
+ "Parsing [MS-RDPEDYC] DYNVC_DATA_FIRST failed");
return 1;
}
len = (cmd >> 2) & 0x03;
if (len == 0)
{
- if (!s_check_rem(s, 1))
+ if (!s_check_rem_and_log(s, 1, "Parsing [MS-RDPEDYC] DYNVC_DATA_FIRST"))
{
return 1;
}
- in_uint8(s, total_bytes);
+ in_uint8(s, total_bytes); /* Length */
}
else if (len == 1)
{
- if (!s_check_rem(s, 2))
+ if (!s_check_rem_and_log(s, 2, "Parsing [MS-RDPEDYC] DYNVC_DATA_FIRST"))
{
return 1;
}
- in_uint16_le(s, total_bytes);
+ in_uint16_le(s, total_bytes); /* Length */
}
else
{
- if (!s_check_rem(s, 4))
+ if (!s_check_rem_and_log(s, 4, "Parsing [MS-RDPEDYC] DYNVC_DATA_FIRST"))
{
return 1;
}
- in_uint32_le(s, total_bytes);
+ in_uint32_le(s, total_bytes); /* Length */
}
bytes = (int) (s->end - s->p);
- LOG_DEVEL(LOG_LEVEL_TRACE, "drdynvc_process_data_first: bytes %d total_bytes %d", bytes, total_bytes);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPEDYC] DYNVC_DATA_FIRST "
+ "ChannelId %d, Length %d, Data (omitted from the log)",
+ chan_id, total_bytes);
+
session = self->sec_layer->rdp_layer->session;
if (chan_id > 255)
{
+ LOG(LOG_LEVEL_ERROR, "Received [MS-RDPEDYC] DYNVC_DATA_FIRST for an "
+ "invalid channel id. Max allowed 255, received %d", chan_id);
return 1;
}
drdynvc = self->drdynvcs + chan_id;
@@ -406,10 +500,17 @@ drdynvc_process_data_first(struct xrdp_channel *self,
return drdynvc->data_first(session->id, chan_id, s->p,
bytes, total_bytes);
}
+ LOG_DEVEL(LOG_LEVEL_WARNING, "Dynamic Virtual Channel %s (%d): "
+ "callback 'data_first' is NULL",
+ XRDP_DRDYNVC_CHANNEL_ID_TO_NAME(self, chan_id),
+ chan_id);
return 0;
}
/*****************************************************************************/
+/*
+ * Process a [MS-RDPEDYC] DYNVC_DATA message.
+ */
static int
drdynvc_process_data(struct xrdp_channel *self,
int cmd, struct stream *s)
@@ -419,15 +520,20 @@ drdynvc_process_data(struct xrdp_channel *self,
int bytes;
struct xrdp_drdynvc *drdynvc;
- if (drdynvc_get_chan_id(s, cmd, &chan_id) != 0)
+ if (drdynvc_get_chan_id(s, cmd, &chan_id) != 0) /* ChannelId */
{
+ LOG(LOG_LEVEL_ERROR, "drdynvc_process_data: drdynvc_get_chan_id failed");
return 1;
}
bytes = (int) (s->end - s->p);
- LOG_DEVEL(LOG_LEVEL_TRACE, "drdynvc_process_data: bytes %d", bytes);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPEDYC] DYNVC_DATA "
+ "ChannelId %d, (re-assembled) Length %d, Data (omitted from the log)",
+ chan_id, bytes);
session = self->sec_layer->rdp_layer->session;
if (chan_id > 255)
{
+ LOG(LOG_LEVEL_ERROR, "Received message for an invalid "
+ "channel id. channel id %d", chan_id);
return 1;
}
drdynvc = self->drdynvcs + chan_id;
@@ -435,10 +541,18 @@ drdynvc_process_data(struct xrdp_channel *self,
{
return drdynvc->data(session->id, chan_id, s->p, bytes);
}
+ LOG_DEVEL(LOG_LEVEL_WARNING, "Dynamic Virtual Channel %s (%d): "
+ "callback 'data' is NULL",
+ XRDP_DRDYNVC_CHANNEL_ID_TO_NAME(self, chan_id),
+ chan_id);
return 0;
}
/*****************************************************************************/
+/**
+ * Process a [MS-RDPBCGR] 2.2.6.1 Virtual Channel PDU and re-assemble the
+ * data chunks as needed.
+ */
static int
xrdp_channel_process_drdynvc(struct xrdp_channel *self,
struct mcs_channel_item *channel,
@@ -451,61 +565,82 @@ xrdp_channel_process_drdynvc(struct xrdp_channel *self,
int rv;
struct stream *ls;
- if (!s_check_rem(s, 8))
+ if (!s_check_rem_and_log(s, 8, "Parsing [MS-RDPBCGR] CHANNEL_PDU_HEADER"))
{
return 1;
}
- in_uint32_le(s, total_length);
- in_uint32_le(s, flags);
- LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_channel_process_drdynvc: total_length %d flags 0x%8.8x",
- total_length, flags);
+ in_uint32_le(s, total_length); /* length */
+ in_uint32_le(s, flags); /* flags */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received header [MS-RDPBCGR] CHANNEL_PDU_HEADER "
+ "length %d, flags 0x%8.8x", total_length, flags);
ls = NULL;
switch (flags & 3)
{
- case 0:
+ case 0: /* not first chunk and not last chunk */
length = (int) (s->end - s->p);
- if (!s_check_rem_out(self->s, length))
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] data chunk (middle) "
+ "length %d", length);
+ if (length > s_rem_out(self->s))
{
+ LOG(LOG_LEVEL_ERROR, "[MS-RDPBCGR] Data chunk length is bigger than "
+ "the remaining chunk buffer size. length %d, remaining %d",
+ length, s_rem_out(self->s));
return 1;
}
- out_uint8a(self->s, s->p, length);
- in_uint8s(s, length);
+ out_uint8a(self->s, s->p, length); /* append data to chunk buffer */
+ in_uint8s(s, length); /* virtualChannelData */
return 0;
- case 1:
+ case 1: /* CHANNEL_FLAG_FIRST */
free_stream(self->s);
make_stream(self->s);
init_stream(self->s, total_length);
length = (int) (s->end - s->p);
- if (!s_check_rem_out(self->s, length))
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] data chunk (first) "
+ "length %d", length);
+ if (length > s_rem_out(self->s))
{
+ LOG(LOG_LEVEL_ERROR, "[MS-RDPBCGR] Data chunk length is bigger than "
+ "the remaining chunk buffer size. length %d, remaining %d",
+ length, s_rem_out(self->s));
return 1;
}
- out_uint8a(self->s, s->p, length);
- in_uint8s(s, length);
+ out_uint8a(self->s, s->p, length); /* append data to chunk buffer */
+ in_uint8s(s, length); /* virtualChannelData */
return 0;
- case 2:
+ case 2: /* CHANNEL_FLAG_LAST */
length = (int) (s->end - s->p);
- if (!s_check_rem_out(self->s, length))
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] data chunk (last) "
+ "length %d", length);
+ if (length > s_rem_out(self->s))
{
+ LOG(LOG_LEVEL_ERROR, "[MS-RDPBCGR] Data chunk length is bigger than "
+ "the remaining chunk buffer size. length %d, remaining %d",
+ length, s_rem_out(self->s));
return 1;
}
- out_uint8a(self->s, s->p, length);
- in_uint8s(s, length);
+ out_uint8a(self->s, s->p, length); /* append data to chunk buffer */
+ in_uint8s(s, length); /* virtualChannelData */
ls = self->s;
break;
- case 3:
+ case 3: /* CHANNEL_FLAG_FIRST and CHANNEL_FLAG_LAST */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] data chunk (first and last) "
+ "length %d", total_length);
ls = s;
break;
default:
- LOG(LOG_LEVEL_ERROR, "xrdp_channel_process_drdynvc: error");
+ LOG(LOG_LEVEL_ERROR, "Received [MS-RDPBCGR] data chunk with "
+ "unknown flag 0x%8.8x", (int) (flags & 3));
return 1;
}
if (ls == NULL)
{
+ LOG(LOG_LEVEL_ERROR, "BUG: ls must not be NULL");
return 1;
}
- in_uint8(ls, cmd); /* read command */
- LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_channel_process_drdynvc: cmd 0x%x", cmd);
+ in_uint8(ls, cmd); /* cbId (low 2 bits), Sp (2 bits), Cmd (hi 4 bits) */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received header [MS-RDPEDYC] "
+ "cbId %d, Sp %d, Cmd 0x%2.2x",
+ (cmd & 0x03), (cmd & 0x0c) >> 2, (cmd & 0xf0) >> 4);
rv = 1;
switch (cmd & 0xf0)
{
@@ -525,16 +660,17 @@ xrdp_channel_process_drdynvc(struct xrdp_channel *self,
rv = drdynvc_process_data(self, cmd, s);
break;
default:
- LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_channel_process_drdynvc: got unknown "
- "command 0x%x", cmd);
+ LOG(LOG_LEVEL_ERROR, "Received header [MS-RDPEDYC] with "
+ "unknown command 0x%2.2x", cmd);
break;
}
- LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_channel_process_drdynvc: rv %d", rv);
return rv;
}
/*****************************************************************************/
-/* returns error */
+/* Process a static ([MS-RDPBCGR] 2.2.6) or dynamic (MS-RDPEDYC 2.2.3)
+ * virtual channel message.
+ * returns error */
/* This is called from the secure layer to process an incoming non global
channel packet.
'chanid' passed in here is the mcs channel id so it MCS_GLOBAL_CHANNEL
@@ -557,12 +693,16 @@ xrdp_channel_process(struct xrdp_channel *self, struct stream *s,
channel = xrdp_channel_get_item(self, channel_id);
if (channel == NULL)
{
- LOG(LOG_LEVEL_ERROR, "xrdp_channel_process, channel not found");
+ LOG(LOG_LEVEL_ERROR,
+ "Received a message for an unknown channel id. channel id %d",
+ chanid);
return 1;
}
if (channel->disabled)
{
- LOG(LOG_LEVEL_WARNING, "xrdp_channel_process, channel disabled");
+ LOG(LOG_LEVEL_WARNING,
+ "Received a message for the disabled channel %s (%d)",
+ channel->name, chanid);
return 0; /* not an error */
}
if (channel_id == self->drdynvc_channel_id)
@@ -570,14 +710,16 @@ xrdp_channel_process(struct xrdp_channel *self, struct stream *s,
return xrdp_channel_process_drdynvc(self, channel, s);
}
rv = 0;
- in_uint32_le(s, length);
- in_uint32_le(s, flags);
+ in_uint32_le(s, length); /* length */
+ in_uint32_le(s, flags); /* flags */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received header [MS-RDPBCGR] CHANNEL_PDU_HEADER "
+ "length %d, flags 0x%8.8x", length, flags);
rv = xrdp_channel_call_callback(self, s, channel_id, length, flags);
return rv;
}
/*****************************************************************************/
-/* drdynvc */
+/* Send a [MS-RDPEDYC] DYNVC_CAPS_VERSION2 message */
static int
xrdp_channel_drdynvc_send_capability_request(struct xrdp_channel *self)
{
@@ -592,11 +734,13 @@ xrdp_channel_drdynvc_send_capability_request(struct xrdp_channel *self)
init_stream(s, 8192);
if (xrdp_channel_init(self, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "xrdp_channel_drdynvc_send_capability_request: xrdp_channel_init failed");
free_stream(s);
return 1;
}
phold = s->p;
- out_uint8(s, 0x50); /* insert cmd */
+ out_uint8(s, 0x50); /* insert cbId (2 bits), Sp (2 bits), cmd (4 bits) */
out_uint8(s, 0x00); /* insert padding */
out_uint16_le(s, 2); /* insert version */
/* channel priority unused for now */
@@ -609,8 +753,13 @@ xrdp_channel_drdynvc_send_capability_request(struct xrdp_channel *self)
total_data_len = (int) (s->end - phold);
flags = CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST;
channel_id = self->drdynvc_channel_id;
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPEDYC] DYNVC_CAPS_VERSION2 "
+ "cbId 0, Sp 0, Cmd 0x05, Version 2, PriorityCharge0 0, "
+ "PriorityCharge1 0, PriorityCharge2 0, PriorityCharge3 0");
if (xrdp_channel_send(self, s, channel_id, total_data_len, flags) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "xrdp_channel_drdynvc_send_capability_request: xrdp_channel_send failed");
free_stream(s);
return 1;
}
@@ -627,7 +776,7 @@ xrdp_channel_drdynvc_start(struct xrdp_channel *self)
struct mcs_channel_item *ci;
struct mcs_channel_item *dci;
- LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_channel_drdynvc_start:");
+
dci = NULL;
count = self->mcs_layer->channel_list->count;
for (index = 0; index < count; index++)
@@ -645,12 +794,24 @@ xrdp_channel_drdynvc_start(struct xrdp_channel *self)
if (dci != NULL)
{
self->drdynvc_channel_id = (dci->chanid - MCS_GLOBAL_CHANNEL) - 1;
+ LOG_DEVEL(LOG_LEVEL_DEBUG,
+ "Initializing Dynamic Virtual Channel with channel id %d",
+ self->drdynvc_channel_id);
xrdp_channel_drdynvc_send_capability_request(self);
}
+ else
+ {
+ LOG(LOG_LEVEL_WARNING,
+ "Dynamic Virtual Channel named 'drdynvc' not found, "
+ "channel not initialized");
+ }
return 0;
}
/*****************************************************************************/
+/*
+ * Send a [MS-RDPEDYC] DYNVC_CREATE_REQ message to request the creation of a channel.
+ */
int
xrdp_channel_drdynvc_open(struct xrdp_channel *self, const char *name,
int flags, struct xrdp_drdynvc_procs *procs,
@@ -670,33 +831,46 @@ xrdp_channel_drdynvc_open(struct xrdp_channel *self, const char *name,
init_stream(s, 8192);
if (xrdp_channel_init(self, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "xrdp_channel_drdynvc_open: xrdp_channel_init failed");
free_stream(s);
return 1;
}
cmd_ptr = s->p;
- out_uint8(s, 0);
+ out_uint8(s, 0); /* set later */
ChId = 1;
while (self->drdynvcs[ChId].status != XRDP_DRDYNVC_STATUS_CLOSED)
{
ChId++;
if (ChId > 255)
{
+ LOG(LOG_LEVEL_ERROR,
+ "Attempting to create a new channel when the maximum "
+ "number of channels have already been created. "
+ "XRDP only supports 255 open channels.");
free_stream(s);
return 1;
}
}
- cbChId = drdynvc_insert_uint_124(s, ChId);
+ cbChId = drdynvc_insert_uint_124(s, ChId); /* ChannelId */
name_length = g_strlen(name);
- out_uint8a(s, name, name_length + 1);
+ out_uint8a(s, name, name_length + 1); /* ChannelName */
chan_pri = 0;
+ /* cbId (low 2 bits), Pri (2 bits), Cmd (hi 4 bits) */
cmd_ptr[0] = CMD_DVC_OPEN_CHANNEL | ((chan_pri << 2) & 0x0c) | cbChId;
static_channel_id = self->drdynvc_channel_id;
static_flags = CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST;
s_mark_end(s);
total_data_len = (int) (s->end - cmd_ptr);
+
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPEDYC] DYNVC_CREATE_REQ "
+ "cbId %d, Pri %d, Cmd 0x%2.2x, ChannelId %d, ChannelName [%s]",
+ cbChId, chan_pri, CMD_DVC_OPEN_CHANNEL, ChId, name);
if (xrdp_channel_send(self, s, static_channel_id, total_data_len,
static_flags) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "Sending [MS-RDPEDYC] DYNVC_CREATE_REQ failed");
free_stream(s);
return 1;
}
@@ -711,6 +885,9 @@ xrdp_channel_drdynvc_open(struct xrdp_channel *self, const char *name,
}
/*****************************************************************************/
+/*
+ * Send a [MS-RDPEDYC] DYNVC_CLOSE message to request the closing of a channel.
+ */
int
xrdp_channel_drdynvc_close(struct xrdp_channel *self, int chan_id)
{
@@ -724,33 +901,48 @@ xrdp_channel_drdynvc_close(struct xrdp_channel *self, int chan_id)
if ((chan_id < 0) || (chan_id > 255))
{
+ LOG(LOG_LEVEL_ERROR, "Attempting to close an invalid channel id. "
+ "channel id %d", chan_id);
return 1;
}
if ((self->drdynvcs[chan_id].status != XRDP_DRDYNVC_STATUS_OPEN) &&
(self->drdynvcs[chan_id].status != XRDP_DRDYNVC_STATUS_OPEN_SENT))
{
/* not open */
+ LOG(LOG_LEVEL_ERROR, "Attempting to close a channel that is not open. "
+ "channel id %d, channel status %s",
+ chan_id,
+ XRDP_DRDYNVC_STATUS_TO_STR(self->drdynvcs[chan_id].status));
return 1;
}
make_stream(s);
init_stream(s, 8192);
if (xrdp_channel_init(self, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "xrdp_channel_drdynvc_close: xrdp_channel_init failed");
free_stream(s);
return 1;
}
cmd_ptr = s->p;
- out_uint8(s, 0);
+ out_uint8(s, 0); /* set later */
ChId = chan_id;
- cbChId = drdynvc_insert_uint_124(s, ChId);
+ cbChId = drdynvc_insert_uint_124(s, ChId); /* ChannelId */
+ /* cbId (low 2 bits), Sp (2 bits), Cmd (hi 4 bits) */
cmd_ptr[0] = CMD_DVC_CLOSE_CHANNEL | cbChId;
static_channel_id = self->drdynvc_channel_id;
static_flags = CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST;
s_mark_end(s);
total_data_len = (int) (s->end - cmd_ptr);
+
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPEDYC] DYNVC_CLOSE "
+ "cbId %d, Sp 0, Cmd 0x%2.2x, ChannelId %d",
+ cbChId, CMD_DVC_OPEN_CHANNEL, ChId);
if (xrdp_channel_send(self, s, static_channel_id, total_data_len,
static_flags) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "xrdp_channel_drdynvc_open: xrdp_channel_send failed");
free_stream(s);
return 1;
}
@@ -760,6 +952,9 @@ xrdp_channel_drdynvc_close(struct xrdp_channel *self, int chan_id)
}
/*****************************************************************************/
+/*
+ * Send a [MS-RDPEDYC] DYNVC_DATA_FIRST message.
+ */
int
xrdp_channel_drdynvc_data_first(struct xrdp_channel *self, int chan_id,
const char *data, int data_bytes,
@@ -776,37 +971,53 @@ xrdp_channel_drdynvc_data_first(struct xrdp_channel *self, int chan_id,
if ((chan_id < 0) || (chan_id > 255))
{
+ LOG(LOG_LEVEL_ERROR, "Attempting to send data to an invalid "
+ "channel id. channel id %d", chan_id);
return 1;
}
if (self->drdynvcs[chan_id].status != XRDP_DRDYNVC_STATUS_OPEN)
{
+ LOG(LOG_LEVEL_ERROR, "Attempting to send data to a channel that "
+ "is not open. channel id %d, channel status %s",
+ chan_id,
+ XRDP_DRDYNVC_STATUS_TO_STR(self->drdynvcs[chan_id].status));
return 1;
}
if (data_bytes > 1590)
{
+ LOG(LOG_LEVEL_ERROR, "Payload for channel id %d is is too big. "
+ "data_bytes %d", chan_id, data_bytes);
return 1;
}
make_stream(s);
init_stream(s, 8192);
if (xrdp_channel_init(self, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "xrdp_channel_drdynvc_data_first: xrdp_channel_init failed");
free_stream(s);
return 1;
}
cmd_ptr = s->p;
- out_uint8(s, 0);
+ out_uint8(s, 0); /* set later */
ChId = chan_id;
- cbChId = drdynvc_insert_uint_124(s, ChId);
- cbTotalDataSize = drdynvc_insert_uint_124(s, total_data_bytes);
- out_uint8p(s, data, data_bytes);
+ cbChId = drdynvc_insert_uint_124(s, ChId); /* ChannelId */
+ cbTotalDataSize = drdynvc_insert_uint_124(s, total_data_bytes); /* Length */
+ out_uint8p(s, data, data_bytes); /* Data */
+ /* cbId (low 2 bits), Len (2 bits), Cmd (hi 4 bits) */
cmd_ptr[0] = CMD_DVC_DATA_FIRST | (cbTotalDataSize << 2) | cbChId;
static_channel_id = self->drdynvc_channel_id;
static_flags = CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST;
s_mark_end(s);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPEDYC] DYNVC_DATA_FIRST "
+ "cbId %d, Len %d, Cmd 0x%2.2x, ChannelId %d, Length %d",
+ cbChId, cbTotalDataSize, CMD_DVC_DATA_FIRST, ChId, total_data_bytes);
total_data_len = (int) (s->end - cmd_ptr);
if (xrdp_channel_send(self, s, static_channel_id, total_data_len,
static_flags) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "xrdp_channel_drdynvc_data_first: xrdp_channel_send failed");
free_stream(s);
return 1;
}
@@ -815,6 +1026,9 @@ xrdp_channel_drdynvc_data_first(struct xrdp_channel *self, int chan_id,
}
/*****************************************************************************/
+/*
+ * Send a [MS-RDPEDYC] DYNVC_DATA message.
+ */
int
xrdp_channel_drdynvc_data(struct xrdp_channel *self, int chan_id,
const char *data, int data_bytes)
@@ -829,36 +1043,52 @@ xrdp_channel_drdynvc_data(struct xrdp_channel *self, int chan_id,
if ((chan_id < 0) || (chan_id > 255))
{
+ LOG(LOG_LEVEL_ERROR, "Attempting to send data to an invalid "
+ "channel id. channel id %d", chan_id);
return 1;
}
if (self->drdynvcs[chan_id].status != XRDP_DRDYNVC_STATUS_OPEN)
{
+ LOG(LOG_LEVEL_ERROR, "Attempting to send data to a channel that "
+ "is not open. channel id %d, channel status %s",
+ chan_id,
+ XRDP_DRDYNVC_STATUS_TO_STR(self->drdynvcs[chan_id].status));
return 1;
}
if (data_bytes > 1590)
{
+ LOG(LOG_LEVEL_ERROR, "Payload for channel id %d is is too big. "
+ "data_bytes %d", chan_id, data_bytes);
return 1;
}
make_stream(s);
init_stream(s, 8192);
if (xrdp_channel_init(self, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "xrdp_channel_drdynvc_data: xrdp_channel_init failed");
free_stream(s);
return 1;
}
cmd_ptr = s->p;
- out_uint8(s, 0);
+ out_uint8(s, 0); /* set later */
ChId = chan_id;
- cbChId = drdynvc_insert_uint_124(s, ChId);
- out_uint8p(s, data, data_bytes);
+ cbChId = drdynvc_insert_uint_124(s, ChId); /* ChannelId */
+ out_uint8p(s, data, data_bytes); /* Data */
+ /* cbId (low 2 bits), Sp (2 bits), Cmd (hi 4 bits) */
cmd_ptr[0] = CMD_DVC_DATA | cbChId;
static_channel_id = self->drdynvc_channel_id;
static_flags = CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST;
s_mark_end(s);
total_data_len = (int) (s->end - cmd_ptr);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPEDYC] DYNVC_DATA "
+ "cbId %d, Sp 0, Cmd 0x%2.2x, ChannelId %d",
+ cbChId, CMD_DVC_DATA_FIRST, ChId);
if (xrdp_channel_send(self, s, static_channel_id, total_data_len,
static_flags) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "xrdp_channel_drdynvc_data: xrdp_channel_send failed");
free_stream(s);
return 1;
}
diff --git a/libxrdp/xrdp_fastpath.c b/libxrdp/xrdp_fastpath.c
index 01853b1c..682c6015 100644
--- a/libxrdp/xrdp_fastpath.c
+++ b/libxrdp/xrdp_fastpath.c
@@ -30,12 +30,11 @@ xrdp_fastpath_create(struct xrdp_sec *owner, struct trans *trans)
{
struct xrdp_fastpath *self;
- LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_fastpath_create");
self = (struct xrdp_fastpath *)g_malloc(sizeof(struct xrdp_fastpath), 1);
self->sec_layer = owner;
self->trans = trans;
self->session = owner->rdp_layer->session;
- LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_fastpath_create");
+
return self;
}
@@ -63,13 +62,13 @@ int
xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s)
{
int fp_hdr;
- int len = 0; /* unused */
+ int len = 0;
int byte;
char *holdp;
- LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_fastpath_recv");
+
holdp = s->p;
- if (!s_check_rem(s, 2))
+ if (!s_check_rem_and_log(s, 2, "Parsing [MS-RDPBCGR] TS_FP_INPUT_PDU"))
{
return 1;
}
@@ -84,7 +83,7 @@ xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s)
byte &= ~(0x80);
len = (byte << 8);
- if (!s_check_rem(s, 1))
+ if (!s_check_rem_and_log(s, 1, "Parsing [MS-RDPBCGR] TS_FP_INPUT_PDU length2"))
{
return 1;
}
@@ -97,7 +96,10 @@ xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s)
len = byte;
}
s->next_packet = holdp + len;
- LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_fastpath_recv");
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received header [MS-RDPBCGR] TS_FP_INPUT_PDU "
+ "fpInputHeader.action (ignored), fpInputHeader.numEvents %d, "
+ "fpInputHeader.flags 0x%1.1x, length %d",
+ self->numEvents, self->secFlags, len);
return 0;
}
@@ -134,6 +136,10 @@ xrdp_fastpath_session_callback(struct xrdp_fastpath *self, int msg,
self->session->callback(self->session->id, msg,
param1, param2, param3, param4);
}
+ else
+ {
+ LOG_DEVEL(LOG_LEVEL_WARNING, "Bug: session is NULL");
+ }
return 0;
}
@@ -163,11 +169,14 @@ xrdp_fastpath_process_EVENT_SCANCODE(struct xrdp_fastpath *self,
int code;
flags = 0;
- if (!s_check_rem(s, 1))
+ if (!s_check_rem_and_log(s, 1, "Parsing [MS-RDPBCGR] TS_FP_KEYBOARD_EVENT"))
{
return 1;
}
in_uint8(s, code); /* keyCode (1 byte) */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_FP_KEYBOARD_EVENT "
+ "eventHeader.eventFlags 0x%2.2x, eventHeader.eventCode (ignored), "
+ "keyCode %d", eventFlags, code);
if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_RELEASE))
{
@@ -205,13 +214,16 @@ xrdp_fastpath_process_EVENT_MOUSE(struct xrdp_fastpath *self,
return 1;
}
- if (!s_check_rem(s, 2 + 2 + 2))
+ if (!s_check_rem_and_log(s, 2 + 2 + 2, "Parsing [MS-RDPBCGR] TS_FP_POINTER_EVENT"))
{
return 1;
}
in_uint16_le(s, pointerFlags); /* pointerFlags (2 bytes) */
in_uint16_le(s, xPos); /* xPos (2 bytes) */
in_uint16_le(s, yPos); /* yPos (2 bytes) */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_FP_POINTER_EVENT "
+ "eventHeader.eventFlags 0x00, eventHeader.eventCode (ignored), "
+ "pointerFlags 0x%4.4x, xPos %d, yPos %d", pointerFlags, xPos, yPos);
xrdp_fastpath_session_callback(self, RDP_INPUT_MOUSE,
xPos, yPos, pointerFlags, 0);
@@ -235,13 +247,18 @@ xrdp_fastpath_process_EVENT_MOUSEX(struct xrdp_fastpath *self,
return 1;
}
- if (!s_check_rem(s, 2 + 2 + 2))
+ if (!s_check_rem_and_log(s, 2 + 2 + 2,
+ "Parsing [MS-RDPBCGR] TS_FP_POINTERX_EVENT"))
{
return 1;
}
in_uint16_le(s, pointerFlags); /* pointerFlags (2 bytes) */
in_uint16_le(s, xPos); /* xPos (2 bytes) */
in_uint16_le(s, yPos); /* yPos (2 bytes) */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_FP_POINTERX_EVENT "
+ "eventHeader.eventFlags 0x%2.2x, eventHeader.eventCode (ignored), "
+ "pointerFlags 0x%4.4x, xPos %d, yPos %d",
+ eventFlags, pointerFlags, xPos, yPos);
xrdp_fastpath_session_callback(self, RDP_INPUT_MOUSEX,
xPos, yPos, pointerFlags, 0);
@@ -263,6 +280,10 @@ xrdp_fastpath_process_EVENT_SYNC(struct xrdp_fastpath *self,
* status of the keyboard toggle keys.
*/
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_FP_SYNC_EVENT"
+ "eventHeader.eventFlags 0x%2.2x, eventHeader.eventCode (ignored), ",
+ eventFlags);
+
xrdp_fastpath_session_callback(self, RDP_INPUT_SYNCHRONIZE,
eventFlags, 0, 0, 0);
@@ -279,11 +300,16 @@ xrdp_fastpath_process_EVENT_UNICODE(struct xrdp_fastpath *self,
int code;
flags = 0;
- if (!s_check_rem(s, 2))
+ if (!s_check_rem_and_log(s, 2, "Parsing [MS-RDPBCGR] TS_FP_UNICODE_KEYBOARD_EVENT"))
{
return 1;
}
in_uint16_le(s, code); /* unicode (2 byte) */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_FP_UNICODE_KEYBOARD_EVENT"
+ "eventHeader.eventFlags 0x%2.2x, eventHeader.eventCode (ignored), "
+ "unicodeCode %d",
+ eventFlags, code);
+
if (eventFlags & FASTPATH_INPUT_KBDFLAGS_RELEASE)
{
flags |= KBD_FLAG_UP;
@@ -315,7 +341,7 @@ xrdp_fastpath_process_input_event(struct xrdp_fastpath *self,
/* process fastpath input events */
for (i = 0; i < self->numEvents; i++)
{
- if (!s_check_rem(s, 1))
+ if (!s_check_rem_and_log(s, 1, "Parsing [MS-RDPBCGR] TS_FP_INPUT_EVENT eventHeader"))
{
return 1;
}
@@ -323,6 +349,9 @@ xrdp_fastpath_process_input_event(struct xrdp_fastpath *self,
eventFlags = (eventHeader & 0x1F);
eventCode = (eventHeader >> 5);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_FP_INPUT_EVENT"
+ "eventHeader.eventFlags 0x%2.2x, eventHeader.eventCode 0x%1.1x",
+ eventFlags, eventCode);
switch (eventCode)
{
@@ -367,8 +396,8 @@ xrdp_fastpath_process_input_event(struct xrdp_fastpath *self,
}
break;
default:
- LOG(LOG_LEVEL_WARNING, "xrdp_fastpath_process_input_event: unknown "
- "eventCode %d", eventCode);
+ LOG(LOG_LEVEL_ERROR, "xrdp_fastpath_process_input_event: "
+ "unknown eventCode %d", eventCode);
break;
}
}
diff --git a/libxrdp/xrdp_iso.c b/libxrdp/xrdp_iso.c
index b8256ab7..c00f4568 100644
--- a/libxrdp/xrdp_iso.c
+++ b/libxrdp/xrdp_iso.c
@@ -17,6 +17,11 @@
* limitations under the License.
*
* iso layer
+ *
+ * Note: [ITU-T X.224] and [ISO/IEC 8073] are essentially two specifications
+ * of the same protocol (see [ITU-T X.224] Appendix I – Differences between
+ * ITU-T Rec. X.224 (1993) and ISO/IEC 8073:1992). The RDP protocol
+ * specification [MS-RDPBCGR] makes reference to the [ITU-T X.224] specificaiton.
*/
#if defined(HAVE_CONFIG_H)
@@ -36,11 +41,9 @@ xrdp_iso_create(struct xrdp_mcs *owner, struct trans *trans)
{
struct xrdp_iso *self;
- LOG_DEVEL(LOG_LEVEL_DEBUG, " in xrdp_iso_create");
self = (struct xrdp_iso *) g_malloc(sizeof(struct xrdp_iso), 1);
self->mcs_layer = owner;
self->trans = trans;
- LOG_DEVEL(LOG_LEVEL_DEBUG, " out xrdp_iso_create");
return self;
}
@@ -77,8 +80,10 @@ xrdp_iso_negotiate_security(struct xrdp_iso *self)
!g_file_readable(client_info->key_file))
{
/* certificate or privkey is not readable */
- LOG(LOG_LEVEL_WARNING, "No readable certificates or "
- "private keys, cannot accept TLS connections");
+ LOG(LOG_LEVEL_ERROR, "Cannot accept TLS connections because "
+ "certificate or private key file is not readable. "
+ "certificate file: [%s], private key file: [%s]",
+ client_info->certificate, client_info->key_file);
self->failureCode = SSL_CERT_NOT_ON_SERVER;
rv = 1; /* error */
}
@@ -89,6 +94,8 @@ xrdp_iso_negotiate_security(struct xrdp_iso *self)
}
else
{
+ LOG(LOG_LEVEL_ERROR, "Server requires TLS for security, "
+ "but the client did not request TLS.");
self->failureCode = SSL_REQUIRED_BY_SERVER;
rv = 1; /* error */
}
@@ -116,40 +123,52 @@ xrdp_iso_negotiate_security(struct xrdp_iso *self)
}
/*****************************************************************************/
-/* returns error */
+/* Process a [MS-RDPBCGR] RDP_NEG_REQ message.
+ * returns error
+ */
static int
xrdp_iso_process_rdp_neg_req(struct xrdp_iso *self, struct stream *s)
{
int flags;
int len;
- if (!s_check_rem(s, 7))
+ if (!s_check_rem_and_log(s, 7, "Parsing [MS-RDPBCGR] RDP_NEG_REQ"))
{
- LOG(LOG_LEVEL_ERROR, "xrdp_iso_process_rdpNegReq: unexpected end-of-record");
return 1;
}
- in_uint8(s, flags);
+ /* The type field has already been read to determine that this function
+ should be called */
+ in_uint8(s, flags); /* flags */
if (flags != 0x0 && flags != 0x8 && flags != 0x1)
{
- LOG(LOG_LEVEL_ERROR, "xrdp_iso_process_rdpNegReq: error, flags: %x", flags);
+ LOG(LOG_LEVEL_ERROR,
+ "Unsupported [MS-RDPBCGR] RDP_NEG_REQ flags: 0x%2.2x", flags);
return 1;
}
- in_uint16_le(s, len);
+ in_uint16_le(s, len); /* length */
if (len != 8)
{
- LOG(LOG_LEVEL_ERROR, "xrdp_iso_process_rdpNegReq: error, length: %x", len);
+ LOG(LOG_LEVEL_ERROR,
+ "Protocol error: [MS-RDPBCGR] RDP_NEG_REQ length must be 8, "
+ "received %d", len);
return 1;
}
- in_uint32_le(s, self->requestedProtocol);
+ in_uint32_le(s, self->requestedProtocol); /* requestedProtocols */
+
+ /* TODO: why is requestedProtocols flag value bigger than 0xb invalid? */
if (self->requestedProtocol > 0xb)
{
- LOG(LOG_LEVEL_ERROR, "xrdp_iso_process_rdpNegReq: error, requestedProtocol: %x",
- self->requestedProtocol);
+ LOG(LOG_LEVEL_ERROR,
+ "Unknown requested protocol flag [MS-RDPBCGR] RDP_NEG_REQ, "
+ "requestedProtocol 0x%8.8x", self->requestedProtocol);
return 1;
}
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received struct [MS-RDPBCGR] RDP_NEG_REQ "
+ "flags 0x%2.2x, length 8, requestedProtocol 0x%8.8x",
+ flags, self->requestedProtocol);
return 0;
}
@@ -163,6 +182,10 @@ xrdp_iso_process_rdp_neg_req(struct xrdp_iso *self, struct stream *s)
* On exit, the TPKT header and the fixed part of the PDU header will have been
* removed from the stream.
*
+ * @param self
+ * @param s [in]
+ * @param code [out]
+ * @param len [out]
* Returns error
*****************************************************************************/
static int
@@ -175,83 +198,110 @@ xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code, int *len)
if (s != self->trans->in_s)
{
- LOG(LOG_LEVEL_WARNING, "xrdp_iso_recv_msg error logic");
+ LOG(LOG_LEVEL_WARNING,
+ "Bug: the input stream is not the same stream as the "
+ "transport input stream");
}
- /* TPKT header is 4 bytes, then first 2 bytes of the X.224 CR-TPDU */
- if (!s_check_rem(s, 6))
+ /* [ITU-T T.123] TPKT header is 4 bytes, then first 2 bytes of the X.224 CR-TPDU */
+ if (!s_check_rem_and_log(s, 6,
+ "Parsing [ITU-T T.123] TPKT header and [ITU-T X.224] TPDU header"))
{
return 1;
}
- in_uint8(s, ver);
- in_uint8s(s, 3); /* Skip reserved field, plus length */
- in_uint8(s, *len);
- in_uint8(s, *code);
+ /* [ITU-T T.123] TPKT header */
+ in_uint8(s, ver); /* version */
+ in_uint8s(s, 3); /* Skip reserved field (1 byte), plus length (2 bytes) */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received header [ITU-T T.123] TPKT "
+ "version %d, length (ignored)", ver);
+
+ /* [ITU-T X.224] TPDU header */
+ in_uint8(s, *len); /* LI (length indicator) */
+ in_uint8(s, *code); /* TPDU code */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received header [ITU-T X.224] TPDU "
+ "length indicator %d, TDPU code 0x%2.2x", *len, *code);
if (ver != 3)
{
- LOG(LOG_LEVEL_ERROR, "xrdp_iso_recv_msg: bad ver");
- LOG_DEVEL_HEXDUMP(LOG_LEVEL_ERROR, "header", s->data, 4);
+ LOG(LOG_LEVEL_ERROR,
+ "Unsupported [ITU-T T.123] TPKT header version: %d", ver);
+ LOG_DEVEL_HEXDUMP(LOG_LEVEL_ERROR, "[ITU-T T.123] TPKT header", s->data, 4);
return 1;
}
if (*len == 255)
{
/* X.224 13.2.1 - reserved value */
- LOG(LOG_LEVEL_ERROR, "xrdp_iso_recv_msg: reserved length encountered");
- LOG_DEVEL_HEXDUMP(LOG_LEVEL_ERROR, "header", s->data, 4);
+ LOG(LOG_LEVEL_ERROR,
+ "[ITU-T X.224] TPDU header: unsupported use of reserved length value");
+ LOG_DEVEL_HEXDUMP(LOG_LEVEL_ERROR, "[ITU-T X.224] TPDU header", s->data + 4, 4);
return 1;
}
if (*code == ISO_PDU_DT)
{
- /* Data PDU : X.224 13.7 */
- if (!s_check_rem(s, 1))
+ /* Data PDU : X.224 13.7 class 0 */
+ if (!s_check_rem_and_log(s, 1, "Parsing [ITU-T X.224] DT-TPDU (Data) header"))
{
return 1;
}
- in_uint8s(s, 1);
+ in_uint8s(s, 1); /* EOT (End of TSDU Mark) (upper 1 bit) and
+ TPDU-NR (Data TPDU Number) (lower 7 bits) */
}
else
{
- /* Other supported PDUs : X.224 13.x */
- if (!s_check_rem(s, 5))
+ /* Other supported X.224 class 0 PDUs all have 5 bytes remaining
+ in the fixed header :
+ CR Connection request (13.3)
+ CC Connection confirm (13.4)
+ DR Disconnect request (13.5) */
+ if (!s_check_rem_and_log(s, 5, "Parsing [ITU-T X.224] Other PDU header"))
{
return 1;
}
- in_uint8s(s, 5);
+ in_uint8s(s, 5); /* DST-REF (2 bytes)
+ SRC-REF (2 bytes)
+ [CR, CC] CLASS OPTION (1 byte) or [DR] REASON (1 byte) */
}
return 0;
}
/*****************************************************************************/
-/* returns error */
+/* Process the header of a [ITU-T X.224] DT-TPDU (Data) message.
+ *
+ * returns error
+ */
int
xrdp_iso_recv(struct xrdp_iso *self, struct stream *s)
{
int code;
int len;
- LOG_DEVEL(LOG_LEVEL_DEBUG, " in xrdp_iso_recv");
-
if (xrdp_iso_recv_msg(self, s, &code, &len) != 0)
{
- LOG(LOG_LEVEL_ERROR, " out xrdp_iso_recv xrdp_iso_recv_msg return non zero");
+ LOG(LOG_LEVEL_ERROR, "xrdp_iso_recv: xrdp_iso_recv_msg failed");
return 1;
}
if (code != ISO_PDU_DT || len != 2)
{
- LOG(LOG_LEVEL_ERROR, " out xrdp_iso_recv code != ISO_PDU_DT or length != 2");
+ LOG(LOG_LEVEL_ERROR, "xrdp_iso_recv only supports processing "
+ "[ITU-T X.224] DT-TPDU (Data) headers. Received TPDU header: "
+ "length indicator %d, TDPU code 0x%2.2x", len, code);
return 1;
}
- LOG_DEVEL(LOG_LEVEL_DEBUG, " out xrdp_iso_recv");
return 0;
}
/*****************************************************************************/
+/*
+ * Send a [ITU-T X.224] CC-TPDU (Connection Confirm) message with
+ * [ITU-T T.123] TPKT header.
+ *
+ * returns error
+ */
static int
xrdp_iso_send_cc(struct xrdp_iso *self)
{
@@ -266,35 +316,44 @@ xrdp_iso_send_cc(struct xrdp_iso *self)
init_stream(s, 8192);
holdp = s->p;
- /* tpkt */
+ /* [ITU-T T.123] TPKT header */
out_uint8(s, 3); /* version */
- out_uint8(s, 0); /* pad */
+ out_uint8(s, 0); /* reserved (padding) */
len_ptr = s->p;
out_uint16_be(s, 0); /* length, set later */
- /* iso */
+
+ /* [ITU-T X.224] CC-TPDU */
len_indicator_ptr = s->p;
- out_uint8(s, 0); /* length indicator, set later */
+ out_uint8(s, 0); /* length indicator, set later */
out_uint8(s, ISO_PDU_CC); /* Connection Confirm PDU */
- out_uint16_be(s, 0);
- out_uint16_be(s, 0x1234);
- out_uint8(s, 0);
- /* rdpNegData */
+ out_uint16_be(s, 0); /* DST-REF */
+ out_uint16_be(s, 0x1234); /* SRC-REF */
+ out_uint8(s, 0); /* CLASS OPTION */
+
+ /* [MS-RDPBCGR] 2.2.1.2 rdpNegData */
if (self->rdpNegData)
{
if (self->failureCode)
{
- out_uint8(s, RDP_NEG_FAILURE);
- out_uint8(s, 0); /* no flags */
- out_uint16_le(s, 8); /* must be 8 */
- out_uint32_le(s, self->failureCode); /* failure code */
+ /* [MS-RDPBCGR] RDP_NEG_FAILURE */
+ out_uint8(s, RDP_NEG_FAILURE); /* type*/
+ out_uint8(s, 0); /* flags (none) */
+ out_uint16_le(s, 8); /* length (must be 8) */
+ out_uint32_le(s, self->failureCode); /* failureCode */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding structure [MS-RDPBCGR] RDP_NEG_FAILURE "
+ "flags 0, length 8, failureCode 0x%8.8x", self->failureCode);
}
else
{
- out_uint8(s, RDP_NEG_RSP);
+ /* [MS-RDPBCGR] RDP_NEG_RSP */
+ out_uint8(s, RDP_NEG_RSP); /* type*/
//TODO: hardcoded flags
out_uint8(s, EXTENDED_CLIENT_DATA_SUPPORTED); /* flags */
- out_uint16_le(s, 8); /* must be 8 */
- out_uint32_le(s, self->selectedProtocol); /* selected protocol */
+ out_uint16_le(s, 8); /* length (must be 8) */
+ out_uint32_le(s, self->selectedProtocol); /* selectedProtocol */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding structure [MS-RDPBCGR] RDP_NEG_RSP "
+ "flags 0, length 8, selectedProtocol 0x%8.8x",
+ self->selectedProtocol);
}
}
s_mark_end(s);
@@ -305,8 +364,15 @@ xrdp_iso_send_cc(struct xrdp_iso *self)
len_ptr[1] = len;
len_indicator_ptr[0] = len_indicator;
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [ITU-T T.123] TPKT "
+ "version 3, length %d", len);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [ITU-T X.224] CC-TPDU (Connection Confirm) "
+ "length indicator %d, DST-REF 0, SRC-REF 0, CLASS OPTION 0",
+ len_indicator);
+
if (trans_write_copy_s(self->trans, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "Sending [ITU-T X.224] CC-TPDU (Connection Confirm) failed");
free_stream(s);
return 1;
}
@@ -317,7 +383,7 @@ xrdp_iso_send_cc(struct xrdp_iso *self)
/*****************************************************************************
* Process an X.224 connection request PDU
*
- * See MS-RDPCGR v20190923 sections 2.2.1.1 and 3.3.5.3.1.
+ * See MS-RDPBCGR v20190923 sections 2.2.1.1 and 3.3.5.3.1.
*
* From the latter, in particular:-
* - The length embedded in the TPKT header MUST be examined for
@@ -339,22 +405,26 @@ xrdp_iso_incoming(struct xrdp_iso *self)
struct stream *s;
int expected_pdu_len;
- LOG_DEVEL(LOG_LEVEL_DEBUG, " in xrdp_iso_incoming");
-
+ LOG_DEVEL(LOG_LEVEL_DEBUG, "[ITU-T X.224] Connection Sequence: receive connection request");
s = libxrdp_force_read(self->trans);
if (s == NULL)
{
+ LOG(LOG_LEVEL_ERROR, "[ITU-T X.224] Connection Sequence: CR-TPDU (Connection Request) failed");
return 1;
}
if (xrdp_iso_recv_msg(self, s, &code, &len) != 0)
{
- LOG(LOG_LEVEL_ERROR, "xrdp_iso_incoming: xrdp_iso_recv_msg returned non zero");
+ LOG(LOG_LEVEL_ERROR, "[ITU-T X.224] Connection Sequence: CR-TPDU (Connection Request) failed");
return 1;
}
if (code != ISO_PDU_CR)
{
+ LOG(LOG_LEVEL_ERROR, "xrdp_iso_incoming only supports processing "
+ "[ITU-T X.224] CR-TPDU (Connection Request) headers. "
+ "Received TPDU header: length indicator %d, TDPU code 0x%2.2x",
+ len, code);
return 1;
}
@@ -369,38 +439,47 @@ xrdp_iso_incoming(struct xrdp_iso *self)
expected_pdu_len = (s->end - s->p) + 6;
if (len != expected_pdu_len)
{
- LOG(LOG_LEVEL_ERROR, "xrdp_iso_incoming: X.224 CR-TPDU length exp %d got %d",
+ LOG(LOG_LEVEL_ERROR,
+ "Invalid length indicator in [ITU-T X.224] CR-TPDU (Connection Request). "
+ "expected %d, received %d",
expected_pdu_len, len);
return 1;
}
- /* process connection request */
+ /* process connection request [MS-RDPBCGR] 2.2.1.1 */
while (s_check_rem(s, 1))
{
- in_uint8(s, cc_type);
+ in_uint8(s, cc_type); /* type or 'C' */
switch (cc_type)
{
default:
+ LOG_DEVEL(LOG_LEVEL_WARNING,
+ "Ignoring unknown structure type in [ITU-T X.224] CR-TPDU (Connection Request). "
+ "type 0x%2.2x", cc_type);
break;
case RDP_NEG_REQ: /* rdpNegReq 1 */
self->rdpNegData = 1;
if (xrdp_iso_process_rdp_neg_req(self, s) != 0)
{
- LOG(LOG_LEVEL_ERROR, "xrdp_iso_incoming: xrdp_iso_process_rdpNegReq returned non zero");
+ LOG(LOG_LEVEL_ERROR,
+ "[ITU-T X.224] Connection Sequence: failed");
return 1;
}
break;
case RDP_CORRELATION_INFO: /* rdpCorrelationInfo 6 */
// TODO
- if (!s_check_rem(s, 1 + 2 + 16 + 16))
+ if (!s_check_rem_and_log(s, 1 + 2 + 16 + 16,
+ "Parsing [MS-RDPBCGR] RDP_NEG_CORRELATION_INFO"))
{
- LOG(LOG_LEVEL_ERROR, "xrdp_iso_incoming: short correlation info");
return 1;
}
in_uint8s(s, 1 + 2 + 16 + 16);
+ LOG_DEVEL(LOG_LEVEL_TRACE,
+ "Received struct [MS-RDPBCGR] RDP_NEG_CORRELATION_INFO "
+ "(all fields ignored)");
break;
- case 'C': /* Cookie */
+ case 'C': /* Cookie or routingToken */
/* The routingToken and cookie fields are both ASCII
* strings starting with the word 'Cookie: ' and
* ending with CR+LF. We ignore both, so we do
@@ -417,6 +496,9 @@ xrdp_iso_incoming(struct xrdp_iso *self)
}
}
}
+ LOG_DEVEL(LOG_LEVEL_TRACE,
+ "Received struct [MS-RDPBCGR] routingToken or cookie "
+ "(ignored)");
break;
}
}
@@ -425,13 +507,14 @@ xrdp_iso_incoming(struct xrdp_iso *self)
rv = xrdp_iso_negotiate_security(self);
/* send connection confirm back to client */
+ LOG_DEVEL(LOG_LEVEL_DEBUG, "[ITU-T X.224] Connection Sequence: send connection confirmation");
if (xrdp_iso_send_cc(self) != 0)
{
- LOG(LOG_LEVEL_ERROR, "xrdp_iso_incoming: xrdp_iso_send_cc returned non zero");
+ LOG(LOG_LEVEL_ERROR, "[ITU-T X.224] Connection Sequence: send connection confirmation failed");
return 1;
}
- LOG_DEVEL(LOG_LEVEL_DEBUG, " out xrdp_iso_incoming");
+ LOG_DEVEL(LOG_LEVEL_DEBUG, "[ITU-T X.224] Connection Sequence: completed");
return rv;
}
@@ -446,27 +529,39 @@ xrdp_iso_init(struct xrdp_iso *self, struct stream *s)
}
/*****************************************************************************/
-/* returns error */
+/* Sends a message with the [ITU-T T.123] TPKT header (T.123 section 8) and
+ * [ITU-T X.224] DT-TPDU (Data) header (X.224 section 13)
+ * returns error
+ */
int
xrdp_iso_send(struct xrdp_iso *self, struct stream *s)
{
int len;
- LOG_DEVEL(LOG_LEVEL_DEBUG, " in xrdp_iso_send");
s_pop_layer(s, iso_hdr);
len = (int) (s->end - s->p);
- out_uint8(s, 3);
- out_uint8(s, 0);
- out_uint16_be(s, len);
- out_uint8(s, 2);
- out_uint8(s, ISO_PDU_DT);
- out_uint8(s, 0x80);
+ /* [ITU-T T.123] TPKT header */
+ out_uint8(s, 3); /* version */
+ out_uint8(s, 0); /* reserved (padding) */
+ out_uint16_be(s, len); /* length */
+
+ /* [ITU-T X.224] DT-TPDU (Data) header */
+ out_uint8(s, 2); /* LI (length indicator) */
+ out_uint8(s, ISO_PDU_DT); /* TPDU code */
+ out_uint8(s, 0x80); /* EOT (End of TSDU Mark) (upper 1 bit) and
+ TPDU-NR (Data TPDU Number) (lower 7 bits) */
+
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [ITU-T T.123] TPKT "
+ "version 3, length %d", len);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [ITU-T X.224] DT-TPDU (Data) "
+ "length indicator 2, TPDU code 0x%2.2x, EOT 1, TPDU-NR 0x00",
+ ISO_PDU_DT);
if (trans_write_copy_s(self->trans, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "xrdp_iso_send: trans_write_copy_s failed");
return 1;
}
- LOG_DEVEL(LOG_LEVEL_DEBUG, " out xrdp_iso_send");
return 0;
}
diff --git a/libxrdp/xrdp_mcs.c b/libxrdp/xrdp_mcs.c
index d37269a0..83b5e760 100644
--- a/libxrdp/xrdp_mcs.c
+++ b/libxrdp/xrdp_mcs.c
@@ -15,7 +15,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
- * mcs layer
+ * mcs layer which implements the Multipoint Communication Service protocol as
+ * specified in [ITU-T T.125]
*/
#if defined(HAVE_CONFIG_H)
@@ -34,7 +35,6 @@ xrdp_mcs_create(struct xrdp_sec *owner, struct trans *trans,
{
struct xrdp_mcs *self;
- LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_create");
self = (struct xrdp_mcs *)g_malloc(sizeof(struct xrdp_mcs), 1);
self->sec_layer = owner;
self->userid = 1;
@@ -43,7 +43,7 @@ xrdp_mcs_create(struct xrdp_sec *owner, struct trans *trans,
self->server_mcs_data = server_mcs_data;
self->iso_layer = xrdp_iso_create(self, trans);
self->channel_list = list_create();
- LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_create");
+
return self;
}
@@ -80,45 +80,58 @@ xrdp_mcs_delete(struct xrdp_mcs *self)
}
/*****************************************************************************/
-/* This function sends channel join confirm */
+/* Send an [ITU-T T.125] DomainMCSPDU message with type ChannelJoinConfirm */
/* returns error = 1 ok = 0 */
static int
xrdp_mcs_send_cjcf(struct xrdp_mcs *self, int userid, int chanid)
{
struct stream *s;
- LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_send_cjcf");
make_stream(s);
init_stream(s, 8192);
if (xrdp_iso_init(self->iso_layer, s) != 0)
{
free_stream(s);
- LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_send_cjcf error");
+ LOG(LOG_LEVEL_ERROR, "xrdp_mcs_send_cjcf: xrdp_iso_init failed");
return 1;
}
- out_uint8(s, (MCS_CJCF << 2) | 2);
- out_uint8(s, 0);
- out_uint16_be(s, userid);
- out_uint16_be(s, chanid); /* TODO Explain why we send this two times */
- out_uint16_be(s, chanid);
+ /* The DomainMCSPDU choice index is a 6-bit int with the next bit as the
+ bit field of the two optional fields in the struct (channelId, nonStandard)
+ */
+ out_uint8(s, (MCS_CJCF << 2) | 0x02); /* DomainMCSPDU choice index,
+ channelId field is present,
+ nonStandard field is not present */
+ out_uint8(s, 0); /* result choice index 0 = rt-successful */
+ out_uint16_be(s, userid); /* initiator */
+ out_uint16_be(s, chanid); /* requested */
+ out_uint16_be(s, chanid); /* channelId (OPTIONAL) */
s_mark_end(s);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sening [ITU-T T.125] ChannelJoinConfirm "
+ "result SUCCESS, initiator %d, requested %d, "
+ "channelId %d", userid, chanid, chanid);
if (xrdp_iso_send(self->iso_layer, s) != 0)
{
free_stream(s);
- LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_send_cjcf error");
+ LOG(LOG_LEVEL_ERROR, "Sening [ITU-T T.125] ChannelJoinConfirm failed");
return 1;
}
free_stream(s);
- LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_send_cjcf");
return 0;
}
/*****************************************************************************/
-/* returns error */
+/*
+ * Processes an [ITU-T T.125] DomainMCSPDU message.
+ *
+ * Note: DomainMCSPDU messages use the ALIGNED BASIC-PER (Packed Encoding Rules)
+ * from [ITU-T X.691].
+ *
+ * returns error
+ */
int
xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan)
{
@@ -127,49 +140,52 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan)
int len;
int userid;
int chanid;
- LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_recv");
+
while (1)
{
if (xrdp_iso_recv(self->iso_layer, s) != 0)
{
- LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_recv, xrdp_iso_recv return non zero");
LOG(LOG_LEVEL_ERROR, "xrdp_mcs_recv: xrdp_iso_recv failed");
return 1;
}
- if (!s_check_rem(s, 1))
+ if (!s_check_rem_and_log(s, 1, "Parsing [ITU-T T.125] DomainMCSPDU"))
{
return 1;
}
+ /* The DomainMCSPDU choice index is a 6-bit int with the 2 least
+ significant bits of the byte as padding */
in_uint8(s, opcode);
- appid = opcode >> 2;
+ appid = opcode >> 2; /* 2-bit padding */
+ LOG_DEVEL(LOG_LEVEL_TRACE,
+ "Received [ITU-T T.125] DomainMCSPDU choice index %d", appid);
if (appid == MCS_DPUM) /* Disconnect Provider Ultimatum */
{
- LOG(LOG_LEVEL_ERROR, "received Disconnect Provider Ultimatum");
- LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_recv appid != MCS_DPUM");
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [ITU-T T.125] DisconnectProviderUltimatum");
+ LOG(LOG_LEVEL_DEBUG, "Recieved disconnection request");
return 1;
}
- /* this is channels getting added from the client */
+ /* MCS_CJRQ: Channel Join ReQuest
+ this is channels getting added from the client */
if (appid == MCS_CJRQ)
{
-
- if (!s_check_rem(s, 4))
+ if (!s_check_rem_and_log(s, 4, "Parsing [ITU-T T.125] ChannelJoinRequest"))
{
return 1;
}
in_uint16_be(s, userid);
in_uint16_be(s, chanid);
- LOG(LOG_LEVEL_DEBUG, "MCS_CJRQ - channel join request received");
- LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_mcs_recv adding channel %4.4x", chanid);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [ITU-T T.125] ChannelJoinRequest "
+ "initiator 0x%4.4x, channelId 0x%4.4x", userid, chanid);
if (xrdp_mcs_send_cjcf(self, userid, chanid) != 0)
{
- LOG(LOG_LEVEL_ERROR, "Non handled error from xrdp_mcs_send_cjcf") ;
+ LOG(LOG_LEVEL_WARNING, "[ITU-T T.125] Channel join sequence: failed");
}
s = libxrdp_force_read(self->iso_layer->trans);
@@ -181,50 +197,73 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan)
continue;
}
-
- if (appid == MCS_SDRQ || appid == MCS_SDIN)
- {
- break;
- }
- else
- {
- LOG(LOG_LEVEL_DEBUG, "Received an unhandled appid:%d", appid);
- }
-
break;
}
if (appid != MCS_SDRQ)
{
- LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_recv err got 0x%x need MCS_SDRQ", appid);
+ LOG(LOG_LEVEL_ERROR, "Received [ITU-T T.125] DomainMCSPDU "
+ "choice index %d is unknown. Expected the DomainMCSPDU to "
+ "contain the type SendDataRequest with index %d",
+ appid, MCS_SDRQ);
return 1;
}
- if (!s_check_rem(s, 6))
+ if (!s_check_rem_and_log(s, 6, "Parsing [ITU-T T.125] SendDataRequest"))
{
return 1;
}
- in_uint8s(s, 2);
- in_uint16_be(s, *chan);
- in_uint8s(s, 1);
- in_uint8(s, len);
+ in_uint8s(s, 2); /* initiator */
+ in_uint16_be(s, *chan); /* channelId */
+ in_uint8s(s, 1); /* dataPriority (4-bits), segmentation (2-bits), padding (2-bits) */
+ in_uint8(s, len); /* userData Length (byte 1) */
- if (len & 0x80)
+ if ((len & 0xC0) == 0x80)
{
- if (!s_check_rem(s, 1))
+ /* From [ITU-T X.691] 11.9.3.7
+ encoding a length determinant if "n" is greater than 127 and
+ less than 16K, then n is encoded using 2 bytes.
+ The first byte will have the two highest order bits set to 1 and 0
+ (ie. len & 0xC0 == 0x80) and the length is encoded as remaining 14 bits of
+ the two bytes (ie. len & 0x3fff). */
+ if (!s_check_rem_and_log(s, 1, "Parsing [ITU-T T.125] SendDataRequest userData Length"))
{
return 1;
}
- in_uint8s(s, 1);
+ in_uint8s(s, 1); /* userData Length (byte 2) */
+ }
+ else if ((len & 0xC0) == 0xC0)
+ {
+ /* From [ITU-T X.691] 11.9.3.8
+ encoding a length determinant if "n" is greater than 16K,
+ then the list of items is fragmented with the length of the first
+ fragment encoded using 1 byte. The two highest order bits are set
+ to 1 and 1 (ie. len & 0xC0 == 0xC0) and the remaining 6 bits contain
+ a multiplyer for 16K (ie. n = (len & 0x3f) * 0x3f)
+ */
+ LOG(LOG_LEVEL_ERROR, "[ITU-T T.125] SendDataRequest with length greater "
+ "than 16K is not supported. len 0x%2.2x", len);
+ return 1;
}
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [ITU-T T.125] SendDataRequest "
+ "initiator (ignored), channelId %d, dataPriority (ignored), "
+ "segmentation (ignored), userData Length (ignored)", *chan);
- LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_recv");
return 0;
}
/*****************************************************************************/
-/* returns error */
+/**
+ * Parse the identifier and length of a [ITU-T X.690] BER (Basic Encoding Rules)
+ * structure header.
+ *
+ * @param self
+ * @param s [in] - the stream to read from
+ * @param tag_val [in] - the expected tag value
+ * @param len [out] - the length of the structure
+ * @returns error
+ */
static int
xrdp_mcs_ber_parse_header(struct xrdp_mcs *self, struct stream *s,
int tag_val, int *len)
@@ -235,7 +274,7 @@ xrdp_mcs_ber_parse_header(struct xrdp_mcs *self, struct stream *s,
if (tag_val > 0xff)
{
- if (!s_check_rem(s, 2))
+ if (!s_check_rem_and_log(s, 2, "Parsing [ITU-T X.690] Identifier"))
{
return 1;
}
@@ -243,7 +282,7 @@ xrdp_mcs_ber_parse_header(struct xrdp_mcs *self, struct stream *s,
}
else
{
- if (!s_check_rem(s, 1))
+ if (!s_check_rem_and_log(s, 1, "Parsing [ITU-T X.690] Identifier"))
{
return 1;
}
@@ -252,10 +291,12 @@ xrdp_mcs_ber_parse_header(struct xrdp_mcs *self, struct stream *s,
if (tag != tag_val)
{
+ LOG(LOG_LEVEL_ERROR, "Parsed [ITU-T X.690] Identifier: "
+ "expected 0x%4.4x, actual 0x%4.4x", tag_val, tag);
return 1;
}
- if (!s_check_rem(s, 1))
+ if (!s_check_rem_and_log(s, 1, "Parsing [ITU-T X.690] Length"))
{
return 1;
}
@@ -269,7 +310,7 @@ xrdp_mcs_ber_parse_header(struct xrdp_mcs *self, struct stream *s,
while (l > 0)
{
- if (!s_check_rem(s, 1))
+ if (!s_check_rem_and_log(s, 1, "Parsing [ITU-T X.690] Length"))
{
return 1;
}
@@ -282,18 +323,14 @@ xrdp_mcs_ber_parse_header(struct xrdp_mcs *self, struct stream *s,
{
*len = l;
}
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Parsed BER header [ITU-T X.690] "
+ "Identifier 0x%4.4x, Length %d", tag, *len);
- if (s_check(s))
- {
- return 0;
- }
- else
- {
- return 1;
- }
+ return 0;
}
/*****************************************************************************/
+/* Parses a [ITU-T T.125] DomainParameters structure encoded using BER */
/* returns error */
static int
xrdp_mcs_parse_domain_params(struct xrdp_mcs *self, struct stream *s)
@@ -302,27 +339,30 @@ xrdp_mcs_parse_domain_params(struct xrdp_mcs *self, struct stream *s)
if (xrdp_mcs_ber_parse_header(self, s, MCS_TAG_DOMAIN_PARAMS, &len) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "Parsing [ITU-T T.125] DomainParameters failed");
return 1;
}
- if ((len < 0) || !s_check_rem(s, len))
+ if (len < 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "Parsing [ITU-T T.125] DomainParameters length field is "
+ "invalid. Expected >= 0, actual %d", len);
return 1;
}
-
- in_uint8s(s, len);
-
- if (s_check(s))
- {
- return 0;
- }
- else
+ if (!s_check_rem_and_log(s, len, "Parsing [ITU-T T.125] DomainParameters"))
{
return 1;
}
+
+ in_uint8s(s, len); /* skip all fields */
+
+ return !s_check_rem_and_log(s, 0, "Parsing [ITU-T T.125] DomainParameters");
}
/*****************************************************************************/
+/* Process a [ITU-T T.125] Connect-Initial message encoded using BER */
/* returns error */
static int
xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self)
@@ -333,249 +373,346 @@ xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self)
s = libxrdp_force_read(self->iso_layer->trans);
if (s == 0)
{
+ LOG(LOG_LEVEL_ERROR, "Processing [ITU-T T.125] Connect-Initial failed");
return 1;
}
if (xrdp_iso_recv(self->iso_layer, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "Processing [ITU-T T.125] Connect-Initial failed");
return 1;
}
if (xrdp_mcs_ber_parse_header(self, s, MCS_CONNECT_INITIAL, &len) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "Parsing [ITU-T T.125] Connect-Initial failed");
return 1;
}
if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_OCTET_STRING, &len) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "Parsing [ITU-T T.125] Connect-Initial callingDomainSelector failed");
return 1;
}
- if ((len < 0) || !s_check_rem(s, len))
+ if (len < 0)
+ {
+ LOG(LOG_LEVEL_ERROR,
+ "Parsing [ITU-T T.125] Connect-Initial callingDomainSelector length field is "
+ "invalid. Expected >= 0, actual %d", len);
+ return 1;
+ }
+ if (!s_check_rem_and_log(s, len, "Parsing [ITU-T T.125] Connect-Initial callingDomainSelector"))
{
return 1;
}
- in_uint8s(s, len);
+ in_uint8s(s, len); /* [ITU-T T.125] Connect-Initial callingDomainSelector */
if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_OCTET_STRING, &len) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "Parsing [ITU-T T.125] Connect-Initial calledDomainSelector failed");
return 1;
}
-
- if ((len < 0) || !s_check_rem(s, len))
+ if (len < 0)
+ {
+ LOG(LOG_LEVEL_ERROR,
+ "Parsing [ITU-T T.125] Connect-Initial calledDomainSelector length field is "
+ "invalid. Expected >= 0, actual %d", len);
+ return 1;
+ }
+ if (!s_check_rem_and_log(s, len, "Parsing [ITU-T T.125] Connect-Initial calledDomainSelector"))
{
return 1;
}
- in_uint8s(s, len);
+ in_uint8s(s, len); /* [ITU-T T.125] Connect-Initial calledDomainSelector */
if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_BOOLEAN, &len) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "Parsing [ITU-T T.125] Connect-Initial upwardFlag failed");
return 1;
}
-
- if ((len < 0) || !s_check_rem(s, len))
+ if (len < 0)
+ {
+ LOG(LOG_LEVEL_ERROR,
+ "Parsing [ITU-T T.125] Connect-Initial upwardFlag length field is "
+ "invalid. Expected >= 0, actual %d", len);
+ return 1;
+ }
+ if (!s_check_rem_and_log(s, len, "Parsing [ITU-T T.125] Connect-Initial upwardFlag"))
{
return 1;
}
- in_uint8s(s, len);
+ in_uint8s(s, len); /* [ITU-T T.125] Connect-Initial upwardFlag */
+ /* [ITU-T T.125] Connect-Initial targetParameters */
if (xrdp_mcs_parse_domain_params(self, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "Parsing [ITU-T T.125] Connect-Initial targetParameters failed");
return 1;
}
+ /* [ITU-T T.125] Connect-Initial minimumParameters */
if (xrdp_mcs_parse_domain_params(self, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "Parsing [ITU-T T.125] Connect-Initial minimumParameters failed");
return 1;
}
+ /* [ITU-T T.125] Connect-Initial maximumParameters */
if (xrdp_mcs_parse_domain_params(self, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "Parsing [ITU-T T.125] Connect-Initial maximumParameters failed");
return 1;
}
if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_OCTET_STRING, &len) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "Parsing [ITU-T T.125] Connect-Initial userData failed");
return 1;
}
-
- /* mcs data can not be zero length */
+ /* mcs userData can not be zero length */
if ((len <= 0) || (len > 16 * 1024))
{
+ LOG(LOG_LEVEL_ERROR,
+ "Parsing [ITU-T T.125] Connect-Initial userData: invalid length. "
+ "Expected min 1, max %d; Actual %d", 16 * 1024, len);
return 1;
}
-
- if (!s_check_rem(s, len))
+ if (!s_check_rem_and_log(s, len, "Parsing [ITU-T T.125] Connect-Initial userData"))
{
return 1;
}
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received header [ITU-T T.125] Connect-Initial "
+ "callingDomainSelector (ignored), calledDomainSelector (ignored), "
+ "upwardFlag (ignored), targetParameters (ignored), "
+ "minimumParameters (ignored), maximumParameters (ignored), "
+ "userData (copied to client_mcs_data)");
/* make a copy of client mcs data */
init_stream(self->client_mcs_data, len);
- out_uint8a(self->client_mcs_data, s->p, len);
+ out_uint8a(self->client_mcs_data, s->p, len); /* [ITU-T T.125] Connect-Initial userData */
in_uint8s(s, len);
s_mark_end(self->client_mcs_data);
- if (s_check_end(s))
- {
- return 0;
- }
- else
+ if (!s_check_end_and_log(s, "MCS protocol error [ITU-T T.125] Connect-Initial"))
{
return 1;
}
+
+ return 0;
+
}
/*****************************************************************************/
-/* returns error */
+/* Processes a [ITU-T T.25] DomainMCSPDU with type ErectDomainRequest
+ *
+ * Note: a parsing example can be found in [MS-RDPBCGR] 4.1.5
+ *
+ * returns error */
static int
xrdp_mcs_recv_edrq(struct xrdp_mcs *self)
{
int opcode;
struct stream *s;
- LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_recv_edrq");
-
s = libxrdp_force_read(self->iso_layer->trans);
if (s == 0)
{
+ LOG(LOG_LEVEL_ERROR, "Processing [ITU-T T.125] ErectDomainRequest failed");
return 1;
}
if (xrdp_iso_recv(self->iso_layer, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "Processing [ITU-T T.125] ErectDomainRequest failed");
return 1;
}
- if (!s_check_rem(s, 1))
+ if (!s_check_rem_and_log(s, 1, "Parsing [ITU-T T.125] DomainMCSPDU"))
{
return 1;
}
+ /* The DomainMCSPDU choice index is a 6-bit int with the next bit as the
+ bit field of the optional field in the struct
+ */
in_uint8(s, opcode);
if ((opcode >> 2) != MCS_EDRQ)
{
+ LOG(LOG_LEVEL_ERROR, "Parsed [ITU-T T.125] DomainMCSPDU choice index "
+ "expected %d, received %d", MCS_EDRQ, (opcode >> 2));
return 1;
}
- if (!s_check_rem(s, 4))
+ if (!s_check_rem_and_log(s, 4, "Parsing [ITU-T T.125] ErectDomainRequest"))
{
return 1;
}
- in_uint8s(s, 2);
- in_uint8s(s, 2);
+ in_uint8s(s, 2); /* subHeight */
+ in_uint8s(s, 2); /* subInterval */
- if (opcode & 2)
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [ITU-T T.125] DomainMCSPDU "
+ "choice index %d (ErectDomainRequest)", (opcode >> 2));
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [ITU-T T.125] ErectDomainRequest "
+ "subHeight (ignored), subInterval (ignored), "
+ "nonStandard (%s)",
+ (opcode & 2) ? "present" : "not present");
+
+ /*
+ * [MS-RDPBCGR] 2.2.1.5 says that the mcsEDrq field is 5 bytes (which have
+ * already been read into the opcode and previous fields), so the
+ * nonStandard field should never be present.
+ */
+ if (opcode & 2) /* ErectDomainRequest v3 nonStandard optional field is present? */
{
- if (!s_check_rem(s, 2))
+ if (!s_check_rem_and_log(s, 2, "Parsing [ITU-T T.125] ErectDomainRequest nonStandard"))
{
return 1;
}
- in_uint16_be(s, self->userid);
+ in_uint16_be(s, self->userid); /* NonStandardParameter.key
+ NonStandardParameter.data */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [ITU-T T.125] DomainMCSPDU "
+ "choice index %d (ErectDomainRequest)", (opcode >> 2));
}
- if (!(s_check_end(s)))
+ if (!s_check_end_and_log(s, "MCS protocol error [ITU-T T.125] ErectDomainRequest"))
{
return 1;
}
- LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_recv_edrq");
return 0;
}
/*****************************************************************************/
-/* returns error */
+/* Processes a [ITU-T T.25] DomainMCSPDU with type AttachUserRequest
+ *
+ * Note: a parsing example can be found in [MS-RDPBCGR] 4.1.6
+ *
+ * returns error */
static int
xrdp_mcs_recv_aurq(struct xrdp_mcs *self)
{
int opcode;
struct stream *s;
- LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_recv_aurq");
-
s = libxrdp_force_read(self->iso_layer->trans);
if (s == 0)
{
+ LOG(LOG_LEVEL_ERROR, "Processing [ITU-T T.125] AttachUserRequest failed");
return 1;
}
if (xrdp_iso_recv(self->iso_layer, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "Processing [ITU-T T.125] AttachUserRequest failed");
return 1;
}
- if (!s_check_rem(s, 1))
+ if (!s_check_rem_and_log(s, 1, "Parsing [ITU-T T.125] DomainMCSPDU"))
{
return 1;
}
+ /* The DomainMCSPDU choice index is a 6-bit int with the next bit as the
+ bit field of the optional field in the struct
+ */
in_uint8(s, opcode);
if ((opcode >> 2) != MCS_AURQ)
{
+ LOG(LOG_LEVEL_ERROR, "Parsed [ITU-T T.125] DomainMCSPDU choice index "
+ "expected %d, received %d", MCS_AURQ, (opcode >> 2));
return 1;
}
+ /*
+ * [MS-RDPBCGR] 2.2.1.6 says that the mcsAUrq field is 1 bytes (which have
+ * already been read into the opcode), so the nonStandard field should
+ * never be present.
+ */
if (opcode & 2)
{
- if (!s_check_rem(s, 2))
+ if (!s_check_rem_and_log(s, 2, "Parsing [ITU-T T.125] AttachUserRequest nonStandard"))
{
return 1;
}
- in_uint16_be(s, self->userid);
+ in_uint16_be(s, self->userid); /* NonStandardParameter.key
+ NonStandardParameter.data */
}
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [ITU-T T.125] DomainMCSPDU "
+ "choice index %d (AttachUserRequest)", (opcode >> 2));
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [ITU-T T.125] AttachUserRequest "
+ "nonStandard (%s)",
+ (opcode & 2) ? "present" : "not present");
- if (!(s_check_end(s)))
+ if (!s_check_end_and_log(s, "MCS protocol error [ITU-T T.125] AttachUserRequest"))
{
return 1;
}
- LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_recv_aurq");
return 0;
}
/*****************************************************************************/
-/* returns error */
+/* Send a [ITU-T T.125] DomainMCSPDU with type AttachUserConfirm.
+ *
+ * Note: a parsing example can be found in [MS-RDPBCGR] 4.1.7
+ *
+ * returns error */
static int
xrdp_mcs_send_aucf(struct xrdp_mcs *self)
{
struct stream *s;
- LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_send_aucf");
make_stream(s);
init_stream(s, 8192);
if (xrdp_iso_init(self->iso_layer, s) != 0)
{
free_stream(s);
- LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_send_aucf error");
+ LOG(LOG_LEVEL_ERROR, "xrdp_mcs_send_aucf: xrdp_iso_init failed");
return 1;
}
- out_uint8(s, ((MCS_AUCF << 2) | 2));
- out_uint8s(s, 1);
- out_uint16_be(s, self->userid);
+ out_uint8(s, ((MCS_AUCF << 2) | 2)); /* AttachUserConfirm
+ optional field initiator is present */
+ out_uint8s(s, 1); /* result = 0 rt-successful */
+ out_uint16_be(s, self->userid); /* initiator */
s_mark_end(s);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [ITU-T T.125] DomainMCSPDU "
+ "of type AttachUserConfirm: result SUCCESS, initiator %d",
+ self->userid);
if (xrdp_iso_send(self->iso_layer, s) != 0)
{
free_stream(s);
- LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_send_aucf error");
+ LOG(LOG_LEVEL_ERROR, "Sending [ITU-T T.125] AttachUserConfirm failed");
return 1;
}
free_stream(s);
- LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_send_aucf");
return 0;
}
/*****************************************************************************/
-/* returns error */
+/* Processes a [ITU-T T.25] DomainMCSPDU with type ChannelJoinRequest
+ *
+ * Note: a parsing example can be found in [MS-RDPBCGR] 4.1.8.1.1
+ *
+ * returns error */
static int
xrdp_mcs_recv_cjrq(struct xrdp_mcs *self)
{
@@ -585,43 +722,61 @@ xrdp_mcs_recv_cjrq(struct xrdp_mcs *self)
s = libxrdp_force_read(self->iso_layer->trans);
if (s == 0)
{
+ LOG(LOG_LEVEL_ERROR, "Processing [ITU-T T.25] ChannelJoinRequest failed");
return 1;
}
if (xrdp_iso_recv(self->iso_layer, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "Processing [ITU-T T.25] ChannelJoinRequest failed");
return 1;
}
- if (!s_check_rem(s, 1))
+ if (!s_check_rem_and_log(s, 1, "Parsing [ITU-T T.125] DomainMCSPDU"))
{
return 1;
}
in_uint8(s, opcode);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [ITU-T T.125] DomainMCSPDU "
+ "choice index %d (ChannelJoinRequest)", (opcode >> 2));
if ((opcode >> 2) != MCS_CJRQ)
{
+ LOG(LOG_LEVEL_ERROR, "Parsed [ITU-T T.125] DomainMCSPDU choice index "
+ "expected %d, received %d", MCS_CJRQ, (opcode >> 2));
return 1;
}
- if (!s_check_rem(s, 4))
+ if (!s_check_rem_and_log(s, 4, "Parsing [ITU-T T.125] ChannelJoinRequest"))
{
return 1;
}
- in_uint8s(s, 4);
+ in_uint8s(s, 4); /* initiator (2 bytes)
+ channelId (2 bytes) */
+ /*
+ * [MS-RDPBCGR] 2.2.1.8 says that the mcsAUrq field is 5 bytes (which have
+ * already been read into the opcode and other fields), so the nonStandard
+ * field should never be present.
+ */
if (opcode & 2)
{
- if (!s_check_rem(s, 2))
+ if (!s_check_rem_and_log(s, 2, "Parsing [ITU-T T.125] ChannelJoinRequest nonStandard"))
{
return 1;
}
- in_uint8s(s, 2);
+ in_uint8s(s, 2); /* NonStandardParameter.key
+ NonStandardParameter.data */
}
- if (!(s_check_end(s)))
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [ITU-T T.125] ChannelJoinRequest "
+ "initiator (ignored), channelId (ignored), "
+ "nonStandard (%s)",
+ (opcode & 2) ? "present" : "not present");
+
+ if (!s_check_end_and_log(s, "MCS protocol error [ITU-T T.125] ChannelJoinRequest"))
{
return 1;
}
@@ -630,7 +785,9 @@ xrdp_mcs_recv_cjrq(struct xrdp_mcs *self)
}
/*****************************************************************************/
-/* returns error */
+/* Write the identifier and length of a [ITU-T X.690] BER (Basic Encoding Rules)
+ * structure header.
+ * returns error */
static int
xrdp_mcs_ber_out_header(struct xrdp_mcs *self, struct stream *s,
int tag_val, int len)
@@ -654,6 +811,8 @@ xrdp_mcs_ber_out_header(struct xrdp_mcs *self, struct stream *s,
out_uint8(s, len);
}
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [ITU-T X.690] Identifier %d, Length %d",
+ tag_val, len);
return 0;
}
@@ -704,15 +863,24 @@ xrdp_mcs_out_domain_params(struct xrdp_mcs *self, struct stream *s,
xrdp_mcs_ber_out_int8(self, s, max_channels);
xrdp_mcs_ber_out_int8(self, s, max_users);
xrdp_mcs_ber_out_int8(self, s, max_tokens);
- xrdp_mcs_ber_out_int8(self, s, 1);
- xrdp_mcs_ber_out_int8(self, s, 0);
- xrdp_mcs_ber_out_int8(self, s, 1);
+ xrdp_mcs_ber_out_int8(self, s, 1); /* numPriorities */
+ xrdp_mcs_ber_out_int8(self, s, 0); /* minThroughput */
+ xrdp_mcs_ber_out_int8(self, s, 1); /* maxHeight */
xrdp_mcs_ber_out_int24(self, s, max_pdu_size);
- xrdp_mcs_ber_out_int8(self, s, 2);
+ xrdp_mcs_ber_out_int8(self, s, 2); /* protocolVersion */
+
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding struct [ITU-T T.125] DomainParameters "
+ "maxChannelIds %d, maxUserIds %d, maxTokenIds %d, numPriorities 1, "
+ "minThroughput 0 B/s, maxHeight 1, maxMCSPDUsize %d, "
+ "protocolVersion 2",
+ max_channels, max_users, max_tokens, max_pdu_size);
return 0;
}
/*****************************************************************************/
-/* prepare server gcc data to send in mcs response msg */
+/* Write an [ITU-T T.124] ConnectData (ALIGNED variant of BASIC-PER) message
+ * with ConnectGCCPDU, ConferenceCreateResponse,
+ * and [MS-RDPBCGR] Server Data Blocks as user data.
+ */
int
xrdp_mcs_out_gcc_data(struct xrdp_sec *self)
{
@@ -724,142 +892,231 @@ xrdp_mcs_out_gcc_data(struct xrdp_sec *self)
int gcc_size;
char *gcc_size_ptr;
char *ud_ptr;
+ int header_length = 0;
+ int server_cert_len = 0;
+ int public_key_blob_len = 0;
+ int key_len = 0;
+ int bit_len = 0;
+ int data_len = 0;
+ int modulus_len = 0;
num_channels = self->mcs_layer->channel_list->count;
num_channels_even = num_channels + (num_channels & 1);
s = &(self->server_mcs_data);
init_stream(s, 8192);
- out_uint16_be(s, 5); /* AsnBerObjectIdentifier */
- out_uint16_be(s, 0x14);
+
+ /* [ITU-T T.124] ConnectData (ALIGNED variant of BASIC-PER) */
+ out_uint16_be(s, 5); /* = 0x00 0x05 */
+ /* t124Identifier choice index = 0 (object) */
+ /* object length = 5 */
+ out_uint16_be(s, 0x14); /* t124Identifier.object = ??? (0x00 0x14 0x7c 0x00 0x01) */
out_uint8(s, 0x7c);
out_uint16_be(s, 1); /* -- */
- out_uint8(s, 0x2a); /* ConnectPDULen */
- out_uint8(s, 0x14);
- out_uint8(s, 0x76);
+ out_uint8(s, 0x2a); /* connectPDU length = 42 */
+ /* connectPDU octet string of type ConnectGCCPDU
+ (unknown where this octet string is defined to be
+ of type ConnectGCCPDU) */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding struct [ITU-T T.124] ConnectData "
+ "t124Identifier.object 0x00 0x14 0x7c 0x00 0x01, connectPDU length %d",
+ 0x2a);
+
+ /* [ITU-T T.124] ConnectGCCPDU (ALIGNED variant of BASIC-PER) */
+ out_uint8(s, 0x14); /* ConnectGCCPDU choice index 1 = ConferenceCreateResponse with userData present */
+
+ /* [ITU-T T.124] ConferenceCreateResponse (ALIGNED variant of BASIC-PER) */
+ out_uint8(s, 0x76); /* nodeID = 31219 - 1001 (PER offset for min value)
+ = 30218 (big-endian 0x760a) */
out_uint8(s, 0x0a);
- out_uint8(s, 1);
- out_uint8(s, 1);
- out_uint8(s, 0);
- out_uint16_le(s, 0xc001);
- out_uint8(s, 0);
+ out_uint8(s, 1); /* tag length */
+ out_uint8(s, 1); /* tag */
+ out_uint8(s, 0); /* result = 0 (success) */
+ out_uint16_le(s, 0xc001); /* userData set count = 1 (0x01),
+ userData.isPresent = 0x80 (yes) | userData.key choice index = 0x40 (1 = h221NonStandard) */
+ out_uint8(s, 0); /* userData.key.h221NonStandard length
+ = 4 - 4 (PER offset for min value) (H221NonStandardIdentifier is an octet string SIZE (4..255))
+ = 0
+ */
+
+ /* [ITU-T H.221] H221NonStandardIdentifier uses country codes and
+ manufactuer codes from [ITU-T T.35]. Unknown why these values are used,
+ maybe this is just copied from the [MS-RDPBCGR] 4.1.4 example which uses
+ the value "McDn" */
out_uint8(s, 0x4d); /* M */
out_uint8(s, 0x63); /* c */
out_uint8(s, 0x44); /* D */
out_uint8(s, 0x6e); /* n */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding struct [ITU-T T.124] ConferenceCreateResponse "
+ "nodeID %d, result SUCCESS", 0x760a + 1001);
+
+ /* ConferenceCreateResponse.userData.key.value (octet string) */
/* GCC Response Total Length - 2 bytes , set later */
gcc_size_ptr = s->p; /* RDPGCCUserDataResponseLength */
out_uint8s(s, 2);
ud_ptr = s->p; /* User Data */
- out_uint16_le(s, SEC_TAG_SRV_INFO);
+ /* [MS-RDPBCGR] TS_UD_HEADER */
+ out_uint16_le(s, SEC_TAG_SRV_INFO); /* type */
if (self->mcs_layer->iso_layer->rdpNegData)
{
- out_uint16_le(s, 12); /* len */
+ out_uint16_le(s, 12); /* length */
}
else
{
- out_uint16_le(s, 8); /* len */
+ out_uint16_le(s, 8); /* length */
}
- out_uint8(s, 4); /* 4 = rdp5 1 = rdp4 */
+ /* [MS-RDPBCGR] TS_UD_SC_CORE */
+ out_uint8(s, 4); /* version (0x00080004 = rdp5, 0x00080001 = rdp4) */
out_uint8(s, 0);
out_uint8(s, 8);
- out_uint8(s, 0);
+ out_uint8(s, 0); /* version (last byte) */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding struct header [MS-RDPBCGR] TS_UD_HEADER "
+ "type 0x%4.4x, length %d",
+ SEC_TAG_SRV_INFO,
+ self->mcs_layer->iso_layer->rdpNegData ? 12 : 8);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding struct [MS-RDPBCGR] TS_UD_SC_CORE "
+ "<Requiered fields> version 0x%8.8x", 0x00080004);
if (self->mcs_layer->iso_layer->rdpNegData)
{
/* RequestedProtocol */
- out_uint32_le(s, self->mcs_layer->iso_layer->requestedProtocol);
- }
- out_uint16_le(s, SEC_TAG_SRV_CHANNELS);
- out_uint16_le(s, 8 + (num_channels_even * 2)); /* len */
- out_uint16_le(s, MCS_GLOBAL_CHANNEL); /* 1003, 0x03eb main channel */
- out_uint16_le(s, num_channels); /* number of other channels */
-
+ out_uint32_le(s, self->mcs_layer->iso_layer->requestedProtocol); /* clientRequestedProtocols */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding struct [MS-RDPBCGR] TS_UD_SC_CORE "
+ "<Optional fields> clientRequestedProtocols 0x%8.8x",
+ self->mcs_layer->iso_layer->requestedProtocol);
+ }
+
+
+ /* [MS-RDPBCGR] TS_UD_HEADER */
+ out_uint16_le(s, SEC_TAG_SRV_CHANNELS); /* type */
+ out_uint16_le(s, 8 + (num_channels_even * 2)); /* length */
+ /* [MS-RDPBCGR] TS_UD_SC_NET */
+ out_uint16_le(s, MCS_GLOBAL_CHANNEL); /* 1003, 0x03eb main channel (MCSChannelId) */
+ out_uint16_le(s, num_channels); /* number of other channels (channelCount) */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding struct header [MS-RDPBCGR] TS_UD_HEADER "
+ "type 0x%4.4x, length %d",
+ SEC_TAG_SRV_CHANNELS, 8 + (num_channels_even * 2));
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding struct [MS-RDPBCGR] TS_UD_SC_NET "
+ "MCSChannelId %d, channelCount %d",
+ MCS_GLOBAL_CHANNEL, num_channels);
for (index = 0; index < num_channels_even; index++)
{
if (index < num_channels)
{
channel = MCS_GLOBAL_CHANNEL + (index + 1);
- out_uint16_le(s, channel);
+ out_uint16_le(s, channel); /* channelIdArray[index] (channel allocated) */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding struct [MS-RDPBCGR] TS_UD_SC_NET channelIdArray[%d] "
+ "channelId %d", index, channel);
}
else
{
- out_uint16_le(s, 0);
+ out_uint16_le(s, 0); /* padding or channelIdArray[index] (channel not allocated) */
}
+
}
- if (self->rsa_key_bytes == 64)
+ if (self->rsa_key_bytes == 64 || self->rsa_key_bytes == 256)
{
- LOG(LOG_LEVEL_DEBUG, "xrdp_sec_out_mcs_data: using 512 bit RSA key");
- out_uint16_le(s, SEC_TAG_SRV_CRYPT);
- out_uint16_le(s, 0x00ec); /* len is 236 */
- out_uint32_le(s, self->crypt_method);
- out_uint32_le(s, self->crypt_level);
- out_uint32_le(s, 32); /* 32 bytes random len */
- out_uint32_le(s, 0xb8); /* 184 bytes rsa info(certificate) len */
- out_uint8a(s, self->server_random, 32);
- /* here to end is certificate */
- /* HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ */
- /* TermService\Parameters\Certificate */
- out_uint32_le(s, 1);
- out_uint32_le(s, 1);
- out_uint32_le(s, 1);
- out_uint16_le(s, SEC_TAG_PUBKEY); /* 0x0006 */
- out_uint16_le(s, 0x005c); /* 92 bytes length of SEC_TAG_PUBKEY */
- out_uint32_le(s, SEC_RSA_MAGIC); /* 0x31415352 'RSA1' */
- out_uint32_le(s, 0x0048); /* 72 bytes modulus len */
- out_uint32_be(s, 0x00020000); /* bit len */
- out_uint32_be(s, 0x3f000000); /* data len */
- out_uint8a(s, self->pub_exp, 4); /* pub exp */
- out_uint8a(s, self->pub_mod, 64); /* pub mod */
- out_uint8s(s, 8); /* pad */
- out_uint16_le(s, SEC_TAG_KEYSIG); /* 0x0008 */
- out_uint16_le(s, 72); /* len */
- out_uint8a(s, self->pub_sig, 64); /* pub sig */
- out_uint8s(s, 8); /* pad */
- }
- else if (self->rsa_key_bytes == 256)
- {
- LOG(LOG_LEVEL_DEBUG, "xrdp_sec_out_mcs_data: using 2048 bit RSA key");
- out_uint16_le(s, SEC_TAG_SRV_CRYPT);
- out_uint16_le(s, 0x01ac); /* len is 428 */
- out_uint32_le(s, self->crypt_method);
- out_uint32_le(s, self->crypt_level);
- out_uint32_le(s, 32); /* 32 bytes random len */
- out_uint32_le(s, 0x178); /* 376 bytes rsa info(certificate) len */
- out_uint8a(s, self->server_random, 32);
- /* here to end is certificate */
+ if (self->rsa_key_bytes == 64)
+ {
+ header_length = 0x00ec; /* length = 236 */
+ server_cert_len = 0xb8; /* serverCertLen (184 bytes) */
+ public_key_blob_len = 0x005c; /* wPublicKeyBlobLen (92 bytes) */
+ key_len = 0x0048; /* keylen (72 bytes = (bitlen / 8) modulus + 8 padding) */
+ bit_len = 512; /* bitlen = 512 */
+ data_len = 63; /* datalen (63 = (bitlen / 8) - 1) */
+ modulus_len = 64;
+ }
+ else /* if (self->rsa_key_bytes == 256) */
+ {
+ header_length = 0x01ac; /* length = 428 */
+ server_cert_len = 0x178; /* serverCertLen (376 bytes) */
+ public_key_blob_len = 0x011c; /* wPublicKeyBlobLen (284 bytes) */
+ key_len = 0x0108; /* keylen (264 bytes = (bitlen / 8) modulus + 8 padding) */
+ bit_len = 2048; /* bitlen = 2048 */
+ data_len = 255; /* datalen (255 = (bitlen / 8) - 1) */
+ modulus_len = 256;
+ }
+ LOG(LOG_LEVEL_DEBUG, "using %d bit RSA key", bit_len);
+
+ /* [MS-RDPBCGR] TS_UD_HEADER */
+ out_uint16_le(s, SEC_TAG_SRV_CRYPT); /* type */
+ out_uint16_le(s, header_length); /* length */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding struct header [MS-RDPBCGR] TS_UD_HEADER "
+ "type 0x%4.4x, length %d", SEC_TAG_SRV_CRYPT, header_length);
+
+ /* [MS-RDPBCGR] TS_UD_SC_SEC1 */
+ out_uint32_le(s, self->crypt_method); /* encryptionMethod */
+ out_uint32_le(s, self->crypt_level); /* encryptionLevel */
+ out_uint32_le(s, 32); /* serverRandomLen */
+ out_uint32_le(s, server_cert_len); /* serverCertLen */
+ out_uint8a(s, self->server_random, 32); /* serverRandom */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding struct [MS-RDPBCGR] TS_UD_SC_SEC1 "
+ "encryptionMethod 0x%8.8x, encryptionLevel 0x%8.8x, "
+ "serverRandomLen 32, serverCertLen %d, serverRandom (omitted), ",
+ self->crypt_method, self->crypt_level, server_cert_len);
+
+ /* (field serverCertificate) [MS-RDPBCGR] SERVER_CERTIFICATE */
/* HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ */
/* TermService\Parameters\Certificate */
- out_uint32_le(s, 1);
- out_uint32_le(s, 1);
- out_uint32_le(s, 1);
- out_uint16_le(s, SEC_TAG_PUBKEY); /* 0x0006 */
- out_uint16_le(s, 0x011c); /* 284 bytes length of SEC_TAG_PUBKEY */
- out_uint32_le(s, SEC_RSA_MAGIC); /* 0x31415352 'RSA1' */
- out_uint32_le(s, 0x0108); /* 264 bytes modulus len */
- out_uint32_be(s, 0x00080000); /* bit len */
- out_uint32_be(s, 0xff000000); /* data len */
- out_uint8a(s, self->pub_exp, 4); /* pub exp */
- out_uint8a(s, self->pub_mod, 256); /* pub mod */
- out_uint8s(s, 8); /* pad */
- out_uint16_le(s, SEC_TAG_KEYSIG); /* 0x0008 */
- out_uint16_le(s, 72); /* len */
- out_uint8a(s, self->pub_sig, 64); /* pub sig */
- out_uint8s(s, 8); /* pad */
+ out_uint32_le(s, 1); /* dwVersion (1 = PROPRIETARYSERVERCERTIFICATE) */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding struct [MS-RDPBCGR] SERVER_CERTIFICATE "
+ "dwVersion.certChainVersion 1 (CERT_CHAIN_VERSION_1), "
+ "dwVersion.t 0 (permanent)");
+
+ /* [MS-RDPBCGR] PROPRIETARYSERVERCERTIFICATE */
+ out_uint32_le(s, 1); /* dwSigAlgId (1 = RSA) */
+ out_uint32_le(s, 1); /* dwKeyAlgId (1 = RSA) */
+ out_uint16_le(s, SEC_TAG_PUBKEY); /* wPublicKeyBlobType (BB_RSA_KEY_BLOB) */
+ out_uint16_le(s, public_key_blob_len); /* wPublicKeyBlobLen */
+
+ /* (field PublicKeyBlob) [MS-RDPBCGR] RSA_PUBLIC_KEY */
+ out_uint32_le(s, SEC_RSA_MAGIC); /* magic (0x31415352 'RSA1') */
+ out_uint32_le(s, key_len); /* keylen */
+ out_uint32_le(s, bit_len); /* bitlen */
+ out_uint32_le(s, data_len); /* datalen */
+ out_uint8a(s, self->pub_exp, 4); /* pubExp */
+ out_uint8a(s, self->pub_mod, modulus_len); /* modulus */
+ out_uint8s(s, 8); /* modulus zero padding */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding struct [MS-RDPBCGR] RSA_PUBLIC_KEY "
+ "magic 0x%8.8x, keylen %d, bitlen %d, datalen %d, "
+ "pubExp <omitted>, modulus <omitted>, ",
+ SEC_RSA_MAGIC, key_len, bit_len, data_len);
+
+ out_uint16_le(s, SEC_TAG_KEYSIG); /* wSignatureBlobType (0x0008 RSA) */
+ out_uint16_le(s, 72); /* wSignatureBlobLen */
+ out_uint8a(s, self->pub_sig, 64); /* SignatureBlob */
+ out_uint8s(s, 8); /* modulus zero padding */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding struct [MS-RDPBCGR] PROPRIETARYSERVERCERTIFICATE "
+ "dwKeyAlgId 1, "
+ "wPublicKeyBlobType 0x%4.4x, "
+ "wPublicKeyBlobLen %d, PublicKeyBlob <see RSA_PUBLIC_KEY above>"
+ "wSignatureBlobType 0x%4.4x, "
+ "wSignatureBlobLen %d, "
+ "SignatureBlob <omitted>",
+ SEC_TAG_PUBKEY, public_key_blob_len,
+ SEC_TAG_KEYSIG, 72);
}
else if (self->rsa_key_bytes == 0) /* no security */
{
- LOG(LOG_LEVEL_DEBUG, "xrdp_sec_out_mcs_data: using no security");
- out_uint16_le(s, SEC_TAG_SRV_CRYPT);
- out_uint16_le(s, 12); /* len is 12 */
- out_uint32_le(s, self->crypt_method);
- out_uint32_le(s, self->crypt_level);
+ LOG(LOG_LEVEL_DEBUG, "using no security");
+ /* [MS-RDPBCGR] TS_UD_HEADER */
+ out_uint16_le(s, SEC_TAG_SRV_CRYPT); /* type*/
+ out_uint16_le(s, 12); /* length */
+ /* [MS-RDPBCGR] TS_UD_SC_SEC1 */
+ out_uint32_le(s, self->crypt_method); /* encryptionMethod */
+ out_uint32_le(s, self->crypt_level); /* encryptionLevel */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding struct header [MS-RDPBCGR] TS_UD_HEADER "
+ "type 0x%4.4x, length %d", SEC_TAG_SRV_CRYPT, 12);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding struct [MS-RDPBCGR] TS_UD_SC_SEC1 "
+ "encryptionMethod 0x%8.8x, encryptionMethod 0x%8.8x",
+ self->crypt_method, self->crypt_level);
}
else
{
- LOG(LOG_LEVEL_ERROR, "xrdp_sec_out_mcs_data: error");
+ LOG(LOG_LEVEL_WARNING,
+ "Unsupported xrdp_sec.rsa_key_bytes value: %d, the client "
+ "will not be sent a [MS-RDPBCGR] TS_UD_SC_SEC1 message.",
+ self->rsa_key_bytes);
}
- /* end certificate */
s_mark_end(s);
gcc_size = (int)(s->end - ud_ptr) | 0x8000;
@@ -869,14 +1126,19 @@ xrdp_mcs_out_gcc_data(struct xrdp_sec *self)
return 0;
}
/*****************************************************************************/
-/* returns error */
+/* Send an [ITU-T T.125] Connect-Response message.
+ *
+ * Note: the xrdp_mcs_out_gcc_data() function must be called (to populate the
+ * xrdp_mcs.server_mcs_data stream) before this method is called.
+ *
+ * returns error
+ */
static int
xrdp_mcs_send_connect_response(struct xrdp_mcs *self)
{
int data_len;
struct stream *s;
- LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_send_connect_response");
make_stream(s);
init_stream(s, 8192);
data_len = (int) (self->server_mcs_data->end - self->server_mcs_data->data);
@@ -885,87 +1147,112 @@ xrdp_mcs_send_connect_response(struct xrdp_mcs *self)
xrdp_mcs_ber_out_header(self, s, MCS_CONNECT_RESPONSE,
data_len > 0x80 ? data_len + 38 : data_len + 36);
xrdp_mcs_ber_out_header(self, s, BER_TAG_RESULT, 1);
- out_uint8(s, 0);
+ out_uint8(s, 0); /* result choice index 0 = rt-successful */
xrdp_mcs_ber_out_header(self, s, BER_TAG_INTEGER, 1);
- out_uint8(s, 0);
+ out_uint8(s, 0); /* calledConnectId */
xrdp_mcs_out_domain_params(self, s, 22, 3, 0, 0xfff8);
xrdp_mcs_ber_out_header(self, s, BER_TAG_OCTET_STRING, data_len);
/* mcs data */
out_uint8a(s, self->server_mcs_data->data, data_len);
s_mark_end(s);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [ITU-T T.125] Connect-Response "
+ "result SUCCESS, calledConnectId 0, "
+ "domainParameters (see xrdp_mcs_out_domain_params() trace logs), "
+ "userData (see xrdp_mcs_out_gcc_data() trace logs and "
+ "hex dump below)");
+ LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "[ITU-T T.125] Connect-Response userData",
+ self->server_mcs_data->data, data_len);
if (xrdp_iso_send(self->iso_layer, s) != 0)
{
free_stream(s);
- LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_send_connect_response error");
+ LOG(LOG_LEVEL_ERROR, "Sending [ITU-T T.125] Connect-Response failed");
return 1;
}
free_stream(s);
- LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_send_connect_response");
return 0;
}
/*****************************************************************************/
-/* returns error */
+/* Process and send the MCS messages for the RDP Connection Sequence
+ * [MS-RDPBCGR] 1.3.1.1
+ *
+ * returns error
+ */
int
xrdp_mcs_incoming(struct xrdp_mcs *self)
{
int index;
- LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_incoming");
-
+ LOG(LOG_LEVEL_DEBUG, "[MCS Connection Sequence] receive connection request");
if (xrdp_mcs_recv_connect_initial(self) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "[MCS Connection Sequence] receive connection request failed");
return 1;
}
/* in xrdp_sec.c */
if (xrdp_sec_process_mcs_data(self->sec_layer) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "[MCS Connection Sequence] Connect Initial PDU with GCC Conference Create Request failed");
return 1;
}
+ LOG(LOG_LEVEL_DEBUG, "[MCS Connection Sequence] construct connection reponse");
if (xrdp_mcs_out_gcc_data(self->sec_layer) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "[MCS Connection Sequence] construct connection reponse failed");
return 1;
}
+ LOG(LOG_LEVEL_DEBUG, "[MCS Connection Sequence] send connection reponse");
if (xrdp_mcs_send_connect_response(self) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "[MCS Connection Sequence] send connection reponse failed");
return 1;
}
+ LOG(LOG_LEVEL_DEBUG, "[MCS Connection Sequence] receive erect domain request");
if (xrdp_mcs_recv_edrq(self) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "[MCS Connection Sequence] receive erect domain request failed");
return 1;
}
+ LOG(LOG_LEVEL_DEBUG, "[MCS Connection Sequence] receive attach user request");
if (xrdp_mcs_recv_aurq(self) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "[MCS Connection Sequence] receive attach user request failed");
return 1;
}
+ LOG(LOG_LEVEL_DEBUG, "[MCS Connection Sequence] send attach user confirm");
if (xrdp_mcs_send_aucf(self) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "[MCS Connection Sequence] send attach user confirm failed");
return 1;
}
for (index = 0; index < self->channel_list->count + 2; index++)
{
+ LOG(LOG_LEVEL_DEBUG, "[MCS Connection Sequence] receive channel join request");
if (xrdp_mcs_recv_cjrq(self) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "[MCS Connection Sequence] receive channel join request failed");
return 1;
}
+ LOG(LOG_LEVEL_DEBUG, "[MCS Connection Sequence] send channel join confirm");
if (xrdp_mcs_send_cjcf(self, self->userid,
self->userid + MCS_USERCHANNEL_BASE + index) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "[MCS Connection Sequence] send channel join confirm failed");
return 1;
}
}
- LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_incoming");
+ LOG(LOG_LEVEL_DEBUG, "[MCS Connection Sequence] completed");
return 0;
}
@@ -1005,19 +1292,20 @@ xrdp_mcs_call_callback(struct xrdp_mcs *self)
}
else
{
- LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_mcs_send, session->callback is nil");
+ LOG_DEVEL(LOG_LEVEL_WARNING, "session->callback is NULL");
}
}
else
{
- LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_mcs_send, session is nil");
+ LOG_DEVEL(LOG_LEVEL_WARNING, "session is NULL");
}
return rv;
}
/*****************************************************************************/
-/* returns error */
+/* Send a [ITU-T T.125] SendDataIndication message
+ * returns error */
int
xrdp_mcs_send(struct xrdp_mcs *self, struct stream *s, int chan)
{
@@ -1025,35 +1313,31 @@ xrdp_mcs_send(struct xrdp_mcs *self, struct stream *s, int chan)
char *lp;
//static int max_len = 0;
- LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_send");
s_pop_layer(s, mcs_hdr);
len = (s->end - s->p) - 8;
if (len > 8192 * 2)
{
- LOG(LOG_LEVEL_WARNING, "error in xrdp_mcs_send, size too big: %d bytes", len);
+ LOG(LOG_LEVEL_WARNING, "xrdp_mcs_send: stream size too big: %d bytes", len);
}
- //if (len > max_len)
- //{
- // max_len = len;
- // g_printf("mcs max length is %d\r\n", max_len);
- //}
- //g_printf("mcs length %d max length is %d\r\n", len, max_len);
- //g_printf("mcs length %d\r\n", len);
- out_uint8(s, MCS_SDIN << 2);
- out_uint16_be(s, self->userid);
- out_uint16_be(s, chan);
- out_uint8(s, 0x70);
+ /* The DomainMCSPDU choice index is a 6-bit int with the 2 least
+ significant bits of the byte as padding */
+ out_uint8(s, MCS_SDIN << 2); /* DomainMCSPDU choice index */
+ out_uint16_be(s, self->userid); /* initiator */
+ out_uint16_be(s, chan); /* channelId */
+ out_uint8(s, 0x70); /* dataPriority (upper 2 bits),
+ segmentation (next 2 bits),
+ padding (4 bits) */
if (len >= 128)
{
len = len | 0x8000;
- out_uint16_be(s, len);
+ out_uint16_be(s, len); /* userData length */
}
else
{
- out_uint8(s, len);
+ out_uint8(s, len); /* userData length */
/* move everything up one byte */
lp = s->p;
@@ -1066,9 +1350,13 @@ xrdp_mcs_send(struct xrdp_mcs *self, struct stream *s, int chan)
s->end--;
}
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [ITU-T T.125] SendDataIndication "
+ "initiator %d, channelId %d, dataPriority %d, segmentation 0x0, "
+ "userData length %d",
+ self->userid, chan, 0x70 >> 6, (0x70 >> 4) & 0x03);
if (xrdp_iso_send(self->iso_layer, s) != 0)
{
- LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_send error");
+ LOG(LOG_LEVEL_ERROR, "xrdp_mcs_send: xrdp_iso_send failed");
return 1;
}
@@ -1079,7 +1367,6 @@ xrdp_mcs_send(struct xrdp_mcs *self, struct stream *s, int chan)
xrdp_mcs_call_callback(self);
}
- LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_send");
return 0;
}
@@ -1097,11 +1384,11 @@ close_rdp_socket(struct xrdp_mcs *self)
trans_shutdown_tls_mode(self->iso_layer->trans);
g_tcp_close(self->iso_layer->trans->sck);
self->iso_layer->trans->sck = 0 ;
- LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_mcs_disconnect - socket closed");
+ LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_mcs_disconnect - socket closed");
return;
}
}
- LOG_DEVEL(LOG_LEVEL_TRACE, "Failed to close socket");
+ LOG_DEVEL(LOG_LEVEL_WARNING, "Failed to close socket");
}
/*****************************************************************************/
@@ -1111,7 +1398,6 @@ xrdp_mcs_disconnect(struct xrdp_mcs *self)
{
struct stream *s;
- LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_disconnect");
make_stream(s);
init_stream(s, 8192);
@@ -1119,24 +1405,25 @@ xrdp_mcs_disconnect(struct xrdp_mcs *self)
{
free_stream(s);
close_rdp_socket(self);
- LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_disconnect error - 1");
+ LOG(LOG_LEVEL_ERROR, "xrdp_mcs_disconnect: xrdp_iso_init failed");
return 1;
}
out_uint8(s, (MCS_DPUM << 2) | 1);
- out_uint8(s, 0x80);
+ out_uint8(s, 0x80); /* reason (upper 3 bits) (4 = rn-channel-purged)*/
s_mark_end(s);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [ITU T.125] DisconnectProviderUltimatum "
+ "reason %d", 0x80 >> 5);
if (xrdp_iso_send(self->iso_layer, s) != 0)
{
free_stream(s);
close_rdp_socket(self);
- LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_disconnect error - 2");
+ LOG(LOG_LEVEL_ERROR, "Sending [ITU T.125] DisconnectProviderUltimatum failed");
return 1;
}
free_stream(s);
close_rdp_socket(self);
- LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_mcs_disconnect - close sent");
return 0;
}
diff --git a/libxrdp/xrdp_mppc_enc.c b/libxrdp/xrdp_mppc_enc.c
index d69953dc..a5837256 100644
--- a/libxrdp/xrdp_mppc_enc.c
+++ b/libxrdp/xrdp_mppc_enc.c
@@ -969,6 +969,10 @@ compress_rdp_5(struct xrdp_mppc_enc *enc, tui8 *srcData, int len)
{
/* compressed data longer than uncompressed data */
/* give up */
+ LOG_DEVEL(LOG_LEVEL_DEBUG, "Compression algorithim produced a compressed "
+ "buffer which is larger than the uncompressed buffer. "
+ "compression ratio %f, flags 0x%x",
+ (float) len / (float) opb_index, enc->flags);
enc->historyOffset = 0;
g_memset(hash_table, 0, enc->buf_len * 2);
g_memset(enc->historyBuffer, 0, enc->buf_len);
@@ -982,10 +986,10 @@ compress_rdp_5(struct xrdp_mppc_enc *enc, tui8 *srcData, int len)
enc->flags |= enc->flagsHold;
enc->flagsHold = 0;
- LOG_DEVEL(LOG_LEVEL_TRACE, "\n");
-
- LOG_DEVEL(LOG_LEVEL_TRACE, "compression ratio: %f", (float) len / (float) enc->bytes_in_opb);
-
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Compression successful. compression ratio %f, "
+ "flags 0x%x, bytes_in_opb %d, historyOffset %d, uncompressed len %d",
+ (float) len / (float) enc->bytes_in_opb, enc->flags,
+ enc->bytes_in_opb, enc->historyOffset, len);
return 1;
}
diff --git a/libxrdp/xrdp_orders.c b/libxrdp/xrdp_orders.c
index 7e65f02f..79b33472 100644
--- a/libxrdp/xrdp_orders.c
+++ b/libxrdp/xrdp_orders.c
@@ -83,6 +83,7 @@ xrdp_orders_reset(struct xrdp_orders *self)
{
if (xrdp_orders_force_send(self) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "xrdp_orders_reset: xrdp_orders_force_send failed");
return 1;
}
g_free(self->orders_state.text_data);
@@ -109,23 +110,29 @@ xrdp_orders_init(struct xrdp_orders *self)
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_orders_init: fastpath");
if (xrdp_rdp_init_fastpath(self->rdp_layer, self->out_s) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "xrdp_orders_init: xrdp_rdp_init_fastpath failed");
return 1;
}
self->order_count_ptr = self->out_s->p;
out_uint8s(self->out_s, 2); /* number of orders, set later */
+ // LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPEGDI] TODO");
}
else
{
- LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_orders_init: slowpath");
if (xrdp_rdp_init_data(self->rdp_layer, self->out_s) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "xrdp_orders_init: xrdp_rdp_init_data failed");
return 1;
}
- out_uint16_le(self->out_s, RDP_UPDATE_ORDERS);
+ out_uint16_le(self->out_s, RDP_UPDATE_ORDERS); /* updateType */
out_uint8s(self->out_s, 2); /* pad */
self->order_count_ptr = self->out_s->p;
out_uint8s(self->out_s, 2); /* number of orders, set later */
out_uint8s(self->out_s, 2); /* pad */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPEGDI] TS_UPDATE_ORDERS_PDU_DATA "
+ "updateType %d (UPDATETYPE_ORDERS), pad2OctetsA <ignored>, "
+ "numberOrders <to be set later>, pad2OctetsB <ignored>",
+ RDP_UPDATE_ORDERS);
}
}
return 0;
@@ -154,6 +161,8 @@ xrdp_orders_send(struct xrdp_orders *self)
if (xrdp_rdp_send_fastpath(self->rdp_layer,
self->out_s, 0) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "xrdp_orders_send: xrdp_rdp_send_fastpath failed");
rv = 1;
}
}
@@ -162,6 +171,8 @@ xrdp_orders_send(struct xrdp_orders *self)
if (xrdp_rdp_send_data(self->rdp_layer, self->out_s,
RDP_DATA_PDU_UPDATE) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "xrdp_orders_send: xrdp_rdp_send_data failed");
rv = 1;
}
}
@@ -225,6 +236,9 @@ xrdp_orders_check(struct xrdp_orders *self, int max_size)
{
if (max_size > max_order_size)
{
+ LOG(LOG_LEVEL_ERROR, "Requested orders max_size (%d) "
+ "is greater than the client connection max_size (%d)",
+ max_size, max_order_size);
return 1;
}
else
@@ -237,7 +251,8 @@ xrdp_orders_check(struct xrdp_orders *self, int max_size)
size = (int)(self->out_s->p - self->order_count_ptr);
if (size < 0)
{
- LOG(LOG_LEVEL_ERROR, "error in xrdp_orders_check, size too small: %d bytes", size);
+ LOG(LOG_LEVEL_ERROR, "Bug: order data length cannot be negative. "
+ "Found length %d bytes", size);
return 1;
}
if (size > max_order_size)
@@ -245,7 +260,9 @@ xrdp_orders_check(struct xrdp_orders *self, int max_size)
/* this suggests someone calls this function without passing the
correct max_size so we end up putting more into the buffer
than we indicate we can */
- LOG(LOG_LEVEL_WARNING, "error in xrdp_orders_check, size too big: %d bytes", size);
+ LOG(LOG_LEVEL_WARNING, "Ignoring Bug: order data length "
+ "is larger than maximum length. Expected %d, actual %d",
+ max_order_size, size);
/* We where getting called with size already greater than
max_order_size
Which I suspect was because the sending of text did not include
@@ -2175,15 +2192,23 @@ xrdp_orders_send_palette(struct xrdp_orders *self, int *palette,
if (xrdp_orders_check(self, 2000) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "xrdp_orders_send_palette: xrdp_orders_check failed");
return 1;
}
self->order_count++;
order_flags = TS_STANDARD | TS_SECONDARY;
out_uint8(self->out_s, order_flags);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPEGDI] DRAWING_ORDER "
+ "controlFlags 0x%2.2x (TS_STANDARD | TS_SECONDARY)", order_flags);
+
len = 1027 - 7; /* length after type minus 7 */
- out_uint16_le(self->out_s, len);
- out_uint16_le(self->out_s, 0); /* flags */
- out_uint8(self->out_s, TS_CACHE_COLOR_TABLE); /* type */
+ out_uint16_le(self->out_s, len); /* orderLength */
+ out_uint16_le(self->out_s, 0); /* extraFlags */
+ out_uint8(self->out_s, TS_CACHE_COLOR_TABLE); /* orderType */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPEGDI] SECONDARY_DRAWING_ORDER_HEADER "
+ "orderLength %d, extraFlags 0x0000, orderType 0x%2.2x (TS_CACHE_COLOR_TABLE)",
+ len, TS_CACHE_COLOR_TABLE);
+
out_uint8(self->out_s, cache_id);
out_uint16_le(self->out_s, 256); /* num colors */
@@ -2194,7 +2219,9 @@ xrdp_orders_send_palette(struct xrdp_orders *self, int *palette,
out_uint8(self->out_s, palette[i] >> 16);
out_uint8(self->out_s, 0);
}
-
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding order [MS-RDPEGDI] CACHE_COLOR_TABLE_ORDER "
+ "cacheIndex %d, numberColors 256, colorTable <omitted from log>",
+ cache_id);
return 0;
}
diff --git a/libxrdp/xrdp_orders_rail.c b/libxrdp/xrdp_orders_rail.c
index 735b92e1..51e5c465 100644
--- a/libxrdp/xrdp_orders_rail.c
+++ b/libxrdp/xrdp_orders_rail.c
@@ -42,12 +42,19 @@ xrdp_orders_send_window_delete(struct xrdp_orders *self, int window_id)
order_size = 11;
if (xrdp_orders_check(self, order_size) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "xrdp_orders_send_window_delete: xrdp_orders_check failed");
return 1;
}
self->order_count++;
order_flags = TS_SECONDARY;
order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
out_uint8(self->out_s, order_flags);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPEGDI] ALTSEC_DRAWING_ORDER_HEADER "
+ "controlFlags.class 0x%1.1x (TS_SECONDARY), "
+ "controlFlags.orderType 0x%2.2x (TS_ALTSEC_WINDOW)",
+ (order_flags & 0x3), (order_flags >> 2));
+
/* orderSize (2 bytes) */
out_uint16_le(self->out_s, order_size);
/* FieldsPresentFlags (4 bytes) */
@@ -55,6 +62,12 @@ xrdp_orders_send_window_delete(struct xrdp_orders *self, int window_id)
out_uint32_le(self->out_s, field_present_flags);
/* windowId (4 bytes) */
out_uint32_le(self->out_s, window_id);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPERP] TS_WINDOW_ORDER_HEADER "
+ "OrderSize %d, "
+ "FieldsPresentFlags 0x%8.8x (WINDOW_ORDER_TYPE_WINDOW | WINDOW_ORDER_STATE_DELETED), "
+ "WindowId 0x%8.8x",
+ order_size, field_present_flags, window_id);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding order [MS-RDPERP] Deleted Window");
return 0;
}
@@ -75,12 +88,19 @@ xrdp_orders_send_window_cached_icon(struct xrdp_orders *self,
order_size = 14;
if (xrdp_orders_check(self, order_size) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "xrdp_orders_send_window_cached_icon: xrdp_orders_check failed");
return 1;
}
self->order_count++;
order_flags = TS_SECONDARY;
order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
out_uint8(self->out_s, order_flags);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPEGDI] ALTSEC_DRAWING_ORDER_HEADER "
+ "controlFlags.class 0x%1.1x (TS_SECONDARY), "
+ "controlFlags.orderType 0x%2.2x (TS_ALTSEC_WINDOW)",
+ (order_flags & 0x3), (order_flags >> 2));
+
/* orderSize (2 bytes) */
out_uint16_le(self->out_s, order_size);
/* FieldsPresentFlags (4 bytes) */
@@ -89,10 +109,17 @@ xrdp_orders_send_window_cached_icon(struct xrdp_orders *self,
out_uint32_le(self->out_s, field_present_flags);
/* windowId (4 bytes) */
out_uint32_le(self->out_s, window_id);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPERP] TS_WINDOW_ORDER_HEADER "
+ "OrderSize %d, FieldsPresentFlags 0x%8.8x, WindowId 0x%8.8x",
+ order_size, field_present_flags, window_id);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding order [MS-RDPERP] Cached Icon");
+
/* CacheEntry (2 bytes) */
out_uint16_le(self->out_s, cache_entry);
/* CacheId (1 byte) */
out_uint8(self->out_s, cache_id);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding order field [MS-RDPERP] TS_CACHED_ICON_INFO "
+ "CacheEntry %d, CacheId %d", cache_entry, cache_id);
return 0;
}
@@ -134,6 +161,18 @@ xrdp_orders_send_ts_icon(struct stream *s, int cache_entry, int cache_id,
}
out_uint8p(s, icon_info->data, icon_info->data_bytes);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding order fields [MS-RDPERP] TS_ICON_INFO "
+ "CacheEntry %d, CacheId %d, Bpp %d, Width %d, Height %d, "
+ "CbColorTable <%s>, "
+ "CbBitsMask %d, CbBitsColor %d, BitsMask <omitted from log>, "
+ "ColorTable <%s>, "
+ "BitsColor <omitted from log>",
+ cache_entry, cache_id, icon_info->bpp, icon_info->width,
+ icon_info->height,
+ (use_cmap ? "present, omitted from log" : "not present"),
+ icon_info->mask_bytes, icon_info->data_bytes,
+ (use_cmap ? "present, omitted from log" : "not present")
+ );
return 0;
}
@@ -169,12 +208,19 @@ xrdp_orders_send_window_icon(struct xrdp_orders *self,
if (xrdp_orders_check(self, order_size) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "xrdp_orders_send_window_icon: xrdp_orders_check failed");
return 1;
}
self->order_count++;
order_flags = TS_SECONDARY;
order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
out_uint8(self->out_s, order_flags);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPEGDI] ALTSEC_DRAWING_ORDER_HEADER "
+ "controlFlags.class 0x%1.1x (TS_SECONDARY), "
+ "controlFlags.orderType 0x%2.2x (TS_ALTSEC_WINDOW)",
+ (order_flags & 0x3), (order_flags >> 2));
+
/* orderSize (2 bytes) */
out_uint16_le(self->out_s, order_size);
/* FieldsPresentFlags (4 bytes) */
@@ -183,6 +229,10 @@ xrdp_orders_send_window_icon(struct xrdp_orders *self,
out_uint32_le(self->out_s, field_present_flags);
/* windowId (4 bytes) */
out_uint32_le(self->out_s, window_id);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPERP] TS_WINDOW_ORDER_HEADER "
+ "OrderSize %d, FieldsPresentFlags 0x%8.8x, WindowId 0x%8.8x",
+ order_size, field_present_flags, window_id);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding order [MS-RDPERP] Window Icon");
xrdp_orders_send_ts_icon(self->out_s, cache_entry, cache_id, icon_info);
@@ -372,23 +422,36 @@ xrdp_orders_send_window_new_update(struct xrdp_orders *self, int window_id,
if (xrdp_orders_check(self, order_size) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "xrdp_orders_send_window_new_update: xrdp_orders_check failed");
return 1;
}
self->order_count++;
order_flags = TS_SECONDARY;
order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
out_uint8(self->out_s, order_flags);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPEGDI] ALTSEC_DRAWING_ORDER_HEADER "
+ "controlFlags.class 0x%1.1x (TS_SECONDARY), "
+ "controlFlags.orderType 0x%2.2x (TS_ALTSEC_WINDOW)",
+ (order_flags & 0x3), (order_flags >> 2));
+
/* orderSize (2 bytes) */
out_uint16_le(self->out_s, order_size);
/* FieldsPresentFlags (4 bytes) */
out_uint32_le(self->out_s, field_present_flags);
/* windowId (4 bytes) */
out_uint32_le(self->out_s, window_id);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPERP] TS_WINDOW_ORDER_HEADER "
+ "OrderSize %d, FieldsPresentFlags 0x%8.8x, WindowId 0x%8.8x",
+ order_size, field_present_flags, window_id);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding order [MS-RDPERP] New or Existing Window (TS_WINDOW_INFO)");
if (field_present_flags & WINDOW_ORDER_FIELD_OWNER)
{
/* ownerWindowId (4 bytes) */
out_uint32_le(self->out_s, window_state->owner_window_id);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding optional field [MS-RDPERP] TS_WINDOW_INFO "
+ "OwnerWindowId 0x%8.8x", window_state->owner_window_id);
}
if (field_present_flags & WINDOW_ORDER_FIELD_STYLE)
@@ -397,18 +460,28 @@ xrdp_orders_send_window_new_update(struct xrdp_orders *self, int window_id,
out_uint32_le(self->out_s, window_state->style);
/* extendedStyle (4 bytes) */
out_uint32_le(self->out_s, window_state->extended_style);
+
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding optional field [MS-RDPERP] TS_WINDOW_INFO "
+ "Style 0x%8.8x, ExtendedStyle 0x%8.8x",
+ window_state->style, window_state->extended_style);
}
if (field_present_flags & WINDOW_ORDER_FIELD_SHOW)
{
/* showState (1 byte) */
out_uint8(self->out_s, window_state->show_state);
+
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding optional field [MS-RDPERP] TS_WINDOW_INFO "
+ "ShowState 0x%2.2x", window_state->show_state);
}
if (field_present_flags & WINDOW_ORDER_FIELD_TITLE)
{
/* titleInfo */
xrdp_orders_send_as_unicode(self->out_s, window_state->title_info);
+
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding optional field [MS-RDPERP] TS_WINDOW_INFO "
+ "TitleInfo %s", window_state->title_info);
}
if (field_present_flags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET)
@@ -417,26 +490,61 @@ xrdp_orders_send_window_new_update(struct xrdp_orders *self, int window_id,
out_uint32_le(self->out_s, window_state->client_offset_x);
/* clientOffsetY (4 bytes) */
out_uint32_le(self->out_s, window_state->client_offset_y);
+
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding optional field [MS-RDPERP] TS_WINDOW_INFO "
+ "ClientOffsetX %d, ClientOffsetY %d",
+ window_state->client_offset_x, window_state->client_offset_y);
}
+ /* TODO: The [MS-RDPERP] spec says that:
+ * The ClientAreaWidth and ClientAreaHeight field only appears if the WndSupportLevel field of the
+ * Window List Capability Set message is set to TS_WINDOW_LEVEL_SUPPORTED_EX
+ * (as specified in [MS-RDPERP] section 2.2.1.1.2)
+ */
if (field_present_flags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE)
{
/* clientAreaWidth (4 bytes) */
out_uint32_le(self->out_s, window_state->client_area_width);
/* clientAreaHeight (4 bytes) */
out_uint32_le(self->out_s, window_state->client_area_height);
- }
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding optional field [MS-RDPERP] TS_WINDOW_INFO "
+ "ClientAreaWidth %d, ClientAreaHeight %d",
+ window_state->client_area_width, window_state->client_area_height);
+ }
+ /* TODO: The [MS-RDPERP] spec section 2.2.1.3.1.2.1 has the following additional fields:
+ * WindowLeftResizeMargin (optional)
+ * WindowRightResizeMargin (optional)
+ * WindowTopResizeMargin (optional)
+ * WindowBottomResizeMargin (optional)
+ */
+
+ /* TODO: The [MS-RDPERP] spec says that:
+ * The RPContent field only appears if the WndSupportLevel field of the
+ * Window List Capability Set message is set to TS_WINDOW_LEVEL_SUPPORTED_EX
+ * (as specified in [MS-RDPERP] section 2.2.1.1.2)
+ */
if (field_present_flags & WINDOW_ORDER_FIELD_RP_CONTENT)
{
/* RPContent (1 byte) */
out_uint8(self->out_s, window_state->rp_content);
+
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding optional field [MS-RDPERP] TS_WINDOW_INFO "
+ "RPContent 0x%2.2x", window_state->rp_content);
}
+ /* TODO: The [MS-RDPERP] spec says that:
+ * The RootParentHandle field only appears if the WndSupportLevel field of the
+ * Window List Capability Set message is set to TS_WINDOW_LEVEL_SUPPORTED_EX
+ * (as specified in [MS-RDPERP] section 2.2.1.1.2)
+ */
if (field_present_flags & WINDOW_ORDER_FIELD_ROOT_PARENT)
{
/* rootParentHandle (4 bytes) */
out_uint32_le(self->out_s, window_state->root_parent_handle);
+
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding optional field [MS-RDPERP] TS_WINDOW_INFO "
+ "RootParentHandle 0x%8.8x", window_state->root_parent_handle);
}
if (field_present_flags & WINDOW_ORDER_FIELD_WND_OFFSET)
@@ -445,6 +553,10 @@ xrdp_orders_send_window_new_update(struct xrdp_orders *self, int window_id,
out_uint32_le(self->out_s, window_state->window_offset_x);
/* windowOffsetY (4 bytes) */
out_uint32_le(self->out_s, window_state->window_offset_y);
+
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding optional field [MS-RDPERP] TS_WINDOW_INFO "
+ "WindowOffsetX %d, WindowOffsetY %d",
+ window_state->window_offset_x, window_state->window_offset_y);
}
if (field_present_flags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA)
@@ -453,6 +565,10 @@ xrdp_orders_send_window_new_update(struct xrdp_orders *self, int window_id,
out_uint32_le(self->out_s, window_state->window_client_delta_x);
/* windowClientDeltaY (4 bytes) */
out_uint32_le(self->out_s, window_state->window_client_delta_y);
+
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding optional field [MS-RDPERP] TS_WINDOW_INFO "
+ "WindowClientDeltaX %d, WindowClientDeltaY %d",
+ window_state->window_client_delta_x, window_state->window_client_delta_y);
}
if (field_present_flags & WINDOW_ORDER_FIELD_WND_SIZE)
@@ -461,6 +577,10 @@ xrdp_orders_send_window_new_update(struct xrdp_orders *self, int window_id,
out_uint32_le(self->out_s, window_state->window_width);
/* windowHeight (4 bytes) */
out_uint32_le(self->out_s, window_state->window_height);
+
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding optional field [MS-RDPERP] TS_WINDOW_INFO "
+ "WindowWidth %d, WindowHeight %d",
+ window_state->window_width, window_state->window_height);
}
if (field_present_flags & WINDOW_ORDER_FIELD_WND_RECTS)
@@ -475,6 +595,9 @@ xrdp_orders_send_window_new_update(struct xrdp_orders *self, int window_id,
out_uint16_le(self->out_s, window_state->window_rects[index].right);
out_uint16_le(self->out_s, window_state->window_rects[index].bottom);
}
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding optional field [MS-RDPERP] TS_WINDOW_INFO "
+ "NumWindowRects %d, WindowRects <omitted from log>",
+ window_state->num_window_rects);
}
if (field_present_flags & WINDOW_ORDER_FIELD_VIS_OFFSET)
@@ -483,6 +606,10 @@ xrdp_orders_send_window_new_update(struct xrdp_orders *self, int window_id,
out_uint32_le(self->out_s, window_state->visible_offset_x);
/* visibleOffsetY (4 bytes) */
out_uint32_le(self->out_s, window_state->visible_offset_y);
+
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding optional field [MS-RDPERP] TS_WINDOW_INFO "
+ "VisibleOffsetX %d, VisibleOffsetY %d",
+ window_state->visible_offset_x, window_state->visible_offset_y);
}
if (field_present_flags & WINDOW_ORDER_FIELD_VISIBILITY)
@@ -497,7 +624,17 @@ xrdp_orders_send_window_new_update(struct xrdp_orders *self, int window_id,
out_uint16_le(self->out_s, window_state->visibility_rects[index].right);
out_uint16_le(self->out_s, window_state->visibility_rects[index].bottom);
}
- }
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding optional field [MS-RDPERP] TS_WINDOW_INFO "
+ "NumVisibilityRects %d, VisibilityRects <omitted from log>",
+ window_state->num_visibility_rects);
+ }
+ /* TODO: The [MS-RDPERP] spec section 2.2.1.3.1.2.1 has the following additional fields:
+ * OverlayDescription (optional, variable)
+ * TaskbarButton (optional)
+ * EnforceServerZOrder (optional)
+ * AppBarState (optional)
+ * AppBarEdge (optional)
+ */
return 0;
}
@@ -516,12 +653,19 @@ xrdp_orders_send_notify_delete(struct xrdp_orders *self, int window_id,
order_size = 15;
if (xrdp_orders_check(self, order_size) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "xrdp_orders_send_notify_delete: xrdp_orders_check failed");
return 1;
}
self->order_count++;
order_flags = TS_SECONDARY;
order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
out_uint8(self->out_s, order_flags);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPEGDI] ALTSEC_DRAWING_ORDER_HEADER "
+ "controlFlags.class 0x%1.1x (TS_SECONDARY), "
+ "controlFlags.orderType 0x%2.2x (TS_ALTSEC_WINDOW)",
+ (order_flags & 0x3), (order_flags >> 2));
+
/* orderSize (2 bytes) */
out_uint16_le(self->out_s, order_size);
/* FieldsPresentFlags (4 bytes) */
@@ -531,6 +675,11 @@ xrdp_orders_send_notify_delete(struct xrdp_orders *self, int window_id,
out_uint32_le(self->out_s, window_id);
/* notifyIconId (4 bytes) */
out_uint32_le(self->out_s, notify_id);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPERP] TS_NOTIFYICON_ORDER_HEADER "
+ "OrderSize %d, FieldsPresentFlags 0x%8.8x, WindowId 0x%8.8x, NotifyIconId 0x%8.8x",
+ order_size, field_present_flags, window_id, notify_id);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding order [MS-RDPERP] Deleted Notification Icons");
+
return 0;
}
@@ -610,12 +759,19 @@ xrdp_orders_send_notify_new_update(struct xrdp_orders *self,
if (xrdp_orders_check(self, order_size) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "xrdp_orders_send_notify_new_update: xrdp_orders_check failed");
return 1;
}
self->order_count++;
order_flags = TS_SECONDARY;
order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
out_uint8(self->out_s, order_flags);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPEGDI] ALTSEC_DRAWING_ORDER_HEADER "
+ "controlFlags.class 0x%1.1x (TS_SECONDARY), "
+ "controlFlags.orderType 0x%2.2x (TS_ALTSEC_WINDOW)",
+ (order_flags & 0x3), (order_flags >> 2));
+
/* orderSize (2 bytes) */
out_uint16_le(self->out_s, order_size);
/* FieldsPresentFlags (4 bytes) */
@@ -624,17 +780,27 @@ xrdp_orders_send_notify_new_update(struct xrdp_orders *self,
out_uint32_le(self->out_s, window_id);
/* notifyIconId (4 bytes) */
out_uint32_le(self->out_s, notify_id);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPERP] TS_NOTIFYICON_ORDER_HEADER "
+ "OrderSize %d, FieldsPresentFlags 0x%8.8x, WindowId 0x%8.8x, NotifyIconId 0x%8.8x",
+ order_size, field_present_flags, window_id, notify_id);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding order [MS-RDPERP] New or Existing Notification Icons");
if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_VERSION)
{
/* Version (4 bytes) */
out_uint32_le(self->out_s, notify_state->version);
+
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding order optional field [MS-RDPERP] "
+ "Version %d", notify_state->version);
}
if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_TIP)
{
/* ToolTip (variable) UNICODE_STRING */
xrdp_orders_send_as_unicode(self->out_s, notify_state->tool_tip);
+
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding order optional field [MS-RDPERP] "
+ "ToolTip %s", notify_state->tool_tip);
}
if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP)
@@ -644,12 +810,20 @@ xrdp_orders_send_notify_new_update(struct xrdp_orders *self,
out_uint32_le(self->out_s, notify_state->infotip.flags);
xrdp_orders_send_as_unicode(self->out_s, notify_state->infotip.text);
xrdp_orders_send_as_unicode(self->out_s, notify_state->infotip.title);
+
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding order optional field [MS-RDPERP] TS_NOTIFY_ICON_INFOTIP "
+ "Timeout %d, InfoFlags 0x%8.8x, InfoTipText %s, Title %s",
+ notify_state->infotip.timeout, notify_state->infotip.flags,
+ notify_state->infotip.text, notify_state->infotip.title);
}
if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_STATE)
{
/* State (4 bytes) */
out_uint32_le(self->out_s, notify_state->state);
+
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding order optional field [MS-RDPERP] "
+ "State %d", notify_state->state);
}
if (field_present_flags & WINDOW_ORDER_ICON)
@@ -666,6 +840,10 @@ xrdp_orders_send_notify_new_update(struct xrdp_orders *self,
out_uint16_le(self->out_s, notify_state->icon_cache_entry);
/* CacheId (1 byte) */
out_uint8(self->out_s, notify_state->icon_cache_id);
+
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding order field [MS-RDPERP] TS_CACHED_ICON_INFO "
+ "CacheEntry %d, CacheId %d",
+ notify_state->icon_cache_entry, notify_state->icon_cache_id);
}
return 0;
@@ -704,21 +882,37 @@ xrdp_orders_send_monitored_desktop(struct xrdp_orders *self,
if (xrdp_orders_check(self, order_size) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "xrdp_orders_send_monitored_desktop: xrdp_orders_check failed");
return 1;
}
self->order_count++;
order_flags = TS_SECONDARY;
order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPEGDI] ALTSEC_DRAWING_ORDER_HEADER "
+ "controlFlags.class 0x%1.1x (TS_SECONDARY), "
+ "controlFlags.orderType 0x%2.2x (TS_ALTSEC_WINDOW)",
+ (order_flags & 0x3), (order_flags >> 2));
+
out_uint8(self->out_s, order_flags);
/* orderSize (2 bytes) */
out_uint16_le(self->out_s, order_size);
/* FieldsPresentFlags (4 bytes) */
out_uint32_le(self->out_s, field_present_flags);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPERP] TS_DESKTOP_ORDER_HEADER "
+ "OrderSize %d, FieldsPresentFlags 0x%8.8x",
+ order_size, field_present_flags);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding order [MS-RDPERP] %s",
+ ((field_present_flags & WINDOW_ORDER_FIELD_DESKTOP_NONE) ?
+ "Non-Monitored Desktop" : "Actively Monitored Desktop"));
if (field_present_flags & WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND)
{
/* ActiveWindowId (4 bytes) */
out_uint32_le(self->out_s, mdo->active_window_id);
+
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding order optional field [MS-RDPERP] "
+ "ActiveWindowId 0x%8.8x", mdo->active_window_id);
}
if (field_present_flags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER)
@@ -731,6 +925,10 @@ xrdp_orders_send_monitored_desktop(struct xrdp_orders *self,
{
out_uint32_le(self->out_s, mdo->window_ids[index]);
}
+
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding order optional field [MS-RDPERP] "
+ "NumWindowIds %d, WindowIds <omitted from log>",
+ mdo->num_window_ids);
}
return 0;
diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c
index 439b26bc..b645a176 100644
--- a/libxrdp/xrdp_rdp.c
+++ b/libxrdp/xrdp_rdp.c
@@ -55,14 +55,14 @@ xrdp_rdp_read_config(const char *xrdp_ini, struct xrdp_client_info *client_info)
items->auto_free = 1;
values = list_create();
values->auto_free = 1;
- LOG_DEVEL(LOG_LEVEL_TRACE, "cfg_file %s", xrdp_ini);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Reading config file %s", xrdp_ini);
file_by_name_read_section(xrdp_ini, "globals", items, values);
for (index = 0; index < items->count; index++)
{
item = (char *)list_get_item(items, index);
value = (char *)list_get_item(values, index);
- LOG_DEVEL(LOG_LEVEL_TRACE, "item %s value %s", item, value);
+ LOG(LOG_LEVEL_DEBUG, "item %s, value %s", item, value);
if (g_strcasecmp(item, "bitmap_cache") == 0)
{
@@ -100,7 +100,7 @@ xrdp_rdp_read_config(const char *xrdp_ini, struct xrdp_client_info *client_info)
}
else
{
- LOG(LOG_LEVEL_ALWAYS, "Warning: Your configured crypt level is "
+ LOG(LOG_LEVEL_WARNING, "Your configured crypt level is "
"undefined, 'high' will be used");
client_info->crypt_level = 3;
}
@@ -110,7 +110,7 @@ xrdp_rdp_read_config(const char *xrdp_ini, struct xrdp_client_info *client_info)
client_info->channels_allowed = g_text2bool(value);
if (client_info->channels_allowed == 0)
{
- LOG(LOG_LEVEL_DEBUG, "Info - All channels are disabled");
+ LOG(LOG_LEVEL_INFO, "All channels are disabled");
}
}
else if (g_strcasecmp(item, "allow_multimon") == 0)
@@ -118,7 +118,7 @@ xrdp_rdp_read_config(const char *xrdp_ini, struct xrdp_client_info *client_info)
client_info->multimon = g_text2bool(value);
if (client_info->multimon == 0)
{
- LOG(LOG_LEVEL_DEBUG, "Info - Multi monitor server support disabled");
+ LOG(LOG_LEVEL_INFO, "Multi monitor server support disabled");
}
}
else if (g_strcasecmp(item, "max_bpp") == 0)
@@ -161,7 +161,7 @@ xrdp_rdp_read_config(const char *xrdp_ini, struct xrdp_client_info *client_info)
}
else
{
- LOG(LOG_LEVEL_ALWAYS, "Warning: Your configured fastpath level is "
+ LOG(LOG_LEVEL_WARNING, "Your configured fastpath level is "
"undefined, fastpath will not be used");
client_info->use_fast_path = 0;
}
@@ -205,7 +205,7 @@ xrdp_rdp_read_config(const char *xrdp_ini, struct xrdp_client_info *client_info)
}
else
{
- LOG(LOG_LEVEL_ERROR, "security_layer=%s is not "
+ LOG(LOG_LEVEL_WARNING, "security_layer=%s is not "
"recognized, will use security_layer=negotiate",
value);
client_info->security_layer = PROTOCOL_SSL | PROTOCOL_HYBRID | PROTOCOL_HYBRID_EX;
@@ -393,33 +393,44 @@ xrdp_rdp_delete(struct xrdp_rdp *self)
}
/*****************************************************************************/
+/* Initialize the stream for sending a [MS-RDPBCGR] Control PDU */
int
xrdp_rdp_init(struct xrdp_rdp *self, struct stream *s)
{
if (xrdp_sec_init(self->sec_layer, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "xrdp_rdp_init: xrdp_sec_init failed");
return 1;
}
- s_push_layer(s, rdp_hdr, 6);
+ s_push_layer(s, rdp_hdr, 6); /* 6 = sizeof(TS_SHARECONTROLHEADER) */
return 0;
}
/*****************************************************************************/
+/* Initialize the stream for sending a [MS-RDPBCGR] Data PDU */
int
xrdp_rdp_init_data(struct xrdp_rdp *self, struct stream *s)
{
if (xrdp_sec_init(self->sec_layer, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "xrdp_rdp_init_data: xrdp_sec_init failed");
return 1;
}
- s_push_layer(s, rdp_hdr, 18);
+ s_push_layer(s, rdp_hdr, 18); /* 18 = sizeof(TS_SHAREDATAHEADER) */
return 0;
}
/*****************************************************************************/
-/* returns error */
+/*
+ Receives and parses pdu code from next data unit.
+
+ @param self
+ @param (in/out) s: the stream to read from. Upon return the stream is ?
+ @param (out) code: the pdu code from the packet
+ returns error
+ */
int
xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code)
{
@@ -429,7 +440,7 @@ xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code)
int chan = 0;
const tui8 *header;
- LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_recv");
+
if (s->next_packet == 0 || s->next_packet >= s->end)
{
/* check for fastpath first */
@@ -438,11 +449,12 @@ xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code)
{
if (xrdp_sec_recv_fastpath(self->sec_layer, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "xrdp_rdp_recv: xrdp_sec_recv_fastpath failed");
return 1;
}
/* next_packet gets set in xrdp_sec_recv_fastpath */
*code = 2; // special code for fastpath input
- LOG_DEVEL(LOG_LEVEL_TRACE, "out (fastpath) xrdp_rdp_recv");
+ LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp_recv: out code 2 (fastpath)");
return 0;
}
@@ -454,13 +466,13 @@ xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code)
{
s->next_packet = 0;
*code = -1;
- LOG_DEVEL(LOG_LEVEL_TRACE, "out (1) xrdp_rdp_recv");
+ LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp_recv: out code -1 (send demand active)");
return 0;
}
if (error != 0)
{
- LOG(LOG_LEVEL_ERROR, "out xrdp_rdp_recv error");
+ LOG(LOG_LEVEL_ERROR, "xrdp_rdp_recv: xrdp_sec_recv failed");
return 1;
}
@@ -470,20 +482,23 @@ xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code)
{
if (xrdp_channel_process(self->sec_layer->chan_layer, s, chan) != 0)
{
- LOG(LOG_LEVEL_ERROR, "xrdp_channel_process returned unhandled error") ;
+ LOG(LOG_LEVEL_ERROR, "xrdp_rdp_recv: xrdp_channel_process failed");
}
}
else
{
if (chan != 1)
{
- LOG(LOG_LEVEL_ERROR, "Wrong channel Id to be handled by xrdp_channel_process %d", chan);
+ LOG_DEVEL(LOG_LEVEL_WARNING,
+ "xrdp_rdp_recv: Wrong channel Id to be handled "
+ "by xrdp_channel_process, channel id %d", chan);
}
}
s->next_packet = 0;
*code = 0;
- LOG_DEVEL(LOG_LEVEL_TRACE, "out (2) xrdp_rdp_recv");
+ LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp_recv: out code 0 (skip data) "
+ "data processed by channel id %d", chan);
return 0;
}
@@ -491,55 +506,66 @@ xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code)
}
else
{
- LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_recv stream not touched");
+ LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp_recv: stream not touched");
s->p = s->next_packet;
}
- if (!s_check_rem(s, 6))
+ if (!s_check_rem_and_log(s, 6, "Parsing [MS-RDPBCGR] TS_SHARECONTROLHEADER"))
{
s->next_packet = 0;
*code = 0;
- len = (int)(s->end - s->p);
- LOG_DEVEL(LOG_LEVEL_TRACE, "out (3) xrdp_rdp_recv: bad RDP packet, length [%d]", len);
+ LOG(LOG_LEVEL_ERROR, "xrdp_rdp_recv: out code 0 (skip data) "
+ "bad RDP packet");
return 0;
}
else
{
- in_uint16_le(s, len);
- /*LOG_DEVEL(LOG_LEVEL_TRACE, "New len received : %d next packet: %d s_end: %d",len,s->next_packet,s->end); */
- in_uint16_le(s, pdu_code);
+ in_uint16_le(s, len); /* totalLength */
+ in_uint16_le(s, pdu_code); /* pduType */
*code = pdu_code & 0xf;
- in_uint8s(s, 2); /* mcs user id */
+ in_uint8s(s, 2); /* pduSource */
s->next_packet += len;
- LOG_DEVEL(LOG_LEVEL_TRACE, "out (4) xrdp_rdp_recv");
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received header [MS-RDPBCGR] TS_SHARECONTROLHEADER "
+ "totalLength %d, pduType.type %s (%d), pduType.PDUVersion %d, "
+ "pduSource (ignored)", len, PDUTYPE_TO_STR(*code), *code,
+ ((pdu_code & 0xfff0) >> 4));
return 0;
}
}
/*****************************************************************************/
+/* Send a [MS-RDPBCGR] Control PDU with for the given pduType with the headers
+ added */
int
xrdp_rdp_send(struct xrdp_rdp *self, struct stream *s, int pdu_type)
{
int len = 0;
- LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_send");
s_pop_layer(s, rdp_hdr);
len = s->end - s->p;
- out_uint16_le(s, len);
- out_uint16_le(s, 0x10 | pdu_type);
- out_uint16_le(s, self->mcs_channel);
+
+ /* TS_SHARECONTROLHEADER */
+ out_uint16_le(s, len); /* totalLength */
+ out_uint16_le(s, 0x10 | pdu_type); /* pduType */
+ out_uint16_le(s, self->mcs_channel); /* pduSource */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPBCGR] TS_SHARECONTROLHEADER "
+ "totalLength %d, pduType.type %s (%d), pduType.PDUVersion %d, "
+ "pduSource %d", len, PDUTYPE_TO_STR(pdu_type & 0xf),
+ pdu_type & 0xf, (((0x10 | pdu_type) & 0xfff0) >> 4),
+ self->mcs_channel);
if (xrdp_sec_send(self->sec_layer, s, MCS_GLOBAL_CHANNEL) != 0)
{
- LOG(LOG_LEVEL_ERROR, "out xrdp_rdp_send error");
+ LOG(LOG_LEVEL_ERROR, "xrdp_rdp_send: xrdp_sec_send failed");
return 1;
}
- LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_send");
return 0;
}
/*****************************************************************************/
+/* Send a [MS-RDPBCGR] Data PDU with for the given pduType2 with the headers
+ added and data compressed */
int
xrdp_rdp_send_data(struct xrdp_rdp *self, struct stream *s,
int data_pdu_type)
@@ -558,7 +584,6 @@ xrdp_rdp_send_data(struct xrdp_rdp *self, struct stream *s,
struct stream ls;
struct xrdp_mppc_enc *mppc_enc;
- LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_send_data");
s_pop_layer(s, rdp_hdr);
len = (int)(s->end - s->p);
pdutype = 0x10 | PDUTYPE_DATAPDU;
@@ -573,10 +598,6 @@ xrdp_rdp_send_data(struct xrdp_rdp *self, struct stream *s,
mppc_enc = self->mppc_enc;
if (compress_rdp(mppc_enc, (tui8 *)(s->p + 18), tocomplen))
{
- LOG_DEVEL(LOG_LEVEL_TRACE, "mppc_encode ok flags 0x%x bytes_in_opb %d historyOffset %d "
- "tocomplen %d", mppc_enc->flags, mppc_enc->bytes_in_opb,
- mppc_enc->historyOffset, tocomplen);
-
clen = mppc_enc->bytes_in_opb + 18;
pdulen = clen;
ctype = mppc_enc->flags;
@@ -600,30 +621,41 @@ xrdp_rdp_send_data(struct xrdp_rdp *self, struct stream *s,
}
else
{
- LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp_send_data: mppc_encode not ok "
- "type %d flags %d", mppc_enc->protocol_type,
- mppc_enc->flags);
+ LOG_DEVEL(LOG_LEVEL_DEBUG,
+ "xrdp_rdp_send_data: compress_rdp failed, sending "
+ "uncompressed data. type %d, flags %d",
+ mppc_enc->protocol_type, mppc_enc->flags);
}
}
- out_uint16_le(s, pdulen);
- out_uint16_le(s, pdutype);
- out_uint16_le(s, self->mcs_channel);
+ /* TS_SHARECONTROLHEADER */
+ out_uint16_le(s, pdulen); /* totalLength */
+ out_uint16_le(s, pdutype); /* pduType */
+ out_uint16_le(s, self->mcs_channel); /* pduSource */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPBCGR] TS_SHARECONTROLHEADER "
+ "totalLength %d, pduType.type %s (%d), pduType.PDUVersion %d, "
+ "pduSource %d", pdulen, PDUTYPE_TO_STR(pdutype & 0xf),
+ pdutype & 0xf, ((pdutype & 0xfff0) >> 4), self->mcs_channel);
+
+ /* TS_SHAREDATAHEADER */
out_uint32_le(s, self->share_id);
- out_uint8(s, 0);
- out_uint8(s, 1);
- out_uint16_le(s, dlen);
- out_uint8(s, data_pdu_type);
- out_uint8(s, ctype);
- out_uint16_le(s, clen);
+ out_uint8(s, 0); /* pad */
+ out_uint8(s, 1); /* streamID */
+ out_uint16_le(s, dlen); /* uncompressedLength */
+ out_uint8(s, data_pdu_type); /* pduType2 */
+ out_uint8(s, ctype); /* compressedType */
+ out_uint16_le(s, clen); /* compressedLength */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPBCGR] TS_SHAREDATAHEADER "
+ "shareID %d, streamID 1, uncompressedLength %d, "
+ "pduType2 0x%2.2x, compressedType 0x%2.2x, compressedLength %d",
+ self->share_id, dlen, data_pdu_type, ctype, clen);
if (xrdp_sec_send(self->sec_layer, s, MCS_GLOBAL_CHANNEL) != 0)
{
- LOG(LOG_LEVEL_ERROR, "out xrdp_rdp_send_data error");
+ LOG(LOG_LEVEL_ERROR, "xrdp_rdp_send_data: xrdp_sec_send failed");
return 1;
}
- LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_send_data");
return 0;
}
@@ -645,6 +677,7 @@ xrdp_rdp_init_fastpath(struct xrdp_rdp *self, struct stream *s)
{
if (xrdp_sec_init_fastpath(self->sec_layer, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "xrdp_rdp_init_fastpath: xrdp_sec_init_fastpath failed");
return 1;
}
if (self->client_info.rdp_compression)
@@ -684,8 +717,9 @@ xrdp_rdp_send_fastpath(struct xrdp_rdp *self, struct stream *s,
struct stream comp_s;
struct stream send_s;
struct xrdp_mppc_enc *mppc_enc;
+ char comp_type_str[7];
+ comp_type_str[0] = '\0';
- LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp_send_fastpath:");
s_pop_layer(s, rdp_hdr);
updateCode = data_pdu_type;
if (self->client_info.rdp_compression)
@@ -729,7 +763,7 @@ xrdp_rdp_send_fastpath(struct xrdp_rdp *self, struct stream *s,
}
}
send_len = no_comp_len;
- LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp_send_fastpath: no_comp_len %d fragmentation %d",
+ LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp_send_fastpath: no_comp_len %d, fragmentation %d",
no_comp_len, fragmentation);
if ((compression != 0) && (no_comp_len > header_bytes + 16))
{
@@ -739,8 +773,6 @@ xrdp_rdp_send_fastpath(struct xrdp_rdp *self, struct stream *s,
to_comp_len))
{
comp_len = mppc_enc->bytes_in_opb + header_bytes;
- LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp_send_fastpath: no_comp_len %d "
- "comp_len %d", no_comp_len, comp_len);
send_len = comp_len;
comp_type = mppc_enc->flags;
/* outputBuffer has 64 bytes preceding it */
@@ -756,9 +788,10 @@ xrdp_rdp_send_fastpath(struct xrdp_rdp *self, struct stream *s,
}
else
{
- LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp_send_fastpath: mppc_encode not ok "
- "type %d flags %d", mppc_enc->protocol_type,
- mppc_enc->flags);
+ LOG(LOG_LEVEL_DEBUG,
+ "compress_rdp failed, sending uncompressed data. "
+ "type %d, flags %d", mppc_enc->protocol_type,
+ mppc_enc->flags);
}
}
updateHeader = (updateCode & 15) |
@@ -768,13 +801,18 @@ xrdp_rdp_send_fastpath(struct xrdp_rdp *self, struct stream *s,
if (compression != 0)
{
out_uint8(&send_s, comp_type);
+ g_snprintf(comp_type_str, 7, "0x%4.4x", comp_type);
}
send_len -= header_bytes;
out_uint16_le(&send_s, send_len);
send_s.end = send_s.p + send_len;
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPBCGR] TS_FP_UPDATE "
+ "updateCode %d, fragmentation %d, compression %d, compressionFlags %s, size %d",
+ updateCode, fragmentation, compression,
+ (compression ? comp_type_str : "(not present)"), send_len);
if (xrdp_sec_send_fastpath(self->sec_layer, &send_s) != 0)
{
- LOG(LOG_LEVEL_ERROR, "xrdp_rdp_send_fastpath: xrdp_fastpath_send failed");
+ LOG(LOG_LEVEL_ERROR, "xrdp_rdp_send_fastpath: xrdp_sec_send_fastpath failed");
return 1;
}
frag_s.p += no_comp_len;
@@ -787,6 +825,8 @@ xrdp_rdp_send_fastpath(struct xrdp_rdp *self, struct stream *s,
}
/*****************************************************************************/
+/* Send a [MS-RDPBCGR] TS_UPDATE_SYNC or TS_FP_UPDATE_SYNCHRONIZE message
+ depending on if the client supports the fast path capability or not */
int
xrdp_rdp_send_data_update_sync(struct xrdp_rdp *self)
{
@@ -794,13 +834,12 @@ xrdp_rdp_send_data_update_sync(struct xrdp_rdp *self)
make_stream(s);
init_stream(s, 8192);
- LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_send_data_update_sync");
if (self->client_info.use_fast_path & 1) /* fastpath output supported */
{
- LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp_send_data_update_sync: fastpath");
if (xrdp_rdp_init_fastpath(self, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "xrdp_rdp_send_data_update_sync: xrdp_rdp_init_fastpath failed");
free_stream(s);
return 1;
}
@@ -809,37 +848,42 @@ xrdp_rdp_send_data_update_sync(struct xrdp_rdp *self)
{
if (xrdp_rdp_init_data(self, s) != 0)
{
- LOG(LOG_LEVEL_ERROR, "out xrdp_rdp_send_data_update_sync error");
+ LOG(LOG_LEVEL_ERROR, "xrdp_rdp_send_data_update_sync: xrdp_rdp_init_data failed");
free_stream(s);
return 1;
}
- out_uint16_le(s, RDP_UPDATE_SYNCHRONIZE);
+ out_uint16_le(s, RDP_UPDATE_SYNCHRONIZE); /* updateType */
out_uint16_le(s, 0); /* pad */
+
}
s_mark_end(s);
if (self->client_info.use_fast_path & 1) /* fastpath output supported */
{
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_FP_UPDATE_SYNCHRONIZE");
if (xrdp_rdp_send_fastpath(self, s,
FASTPATH_UPDATETYPE_SYNCHRONIZE) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "Sending [MS-RDPBCGR] TS_FP_UPDATE_SYNCHRONIZE failed");
free_stream(s);
return 1;
}
}
else /* slowpath */
{
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_UPDATE_SYNC "
+ "updateType %s (%d)",
+ GRAPHICS_UPDATE_TYPE_TO_STR(RDP_UPDATE_SYNCHRONIZE),
+ RDP_UPDATE_SYNCHRONIZE);
if (xrdp_rdp_send_data(self, s, RDP_DATA_PDU_UPDATE) != 0)
{
- LOG(LOG_LEVEL_ERROR, "out xrdp_rdp_send_data_update_sync error");
+ LOG(LOG_LEVEL_ERROR, "Sending [MS-RDPBCGR] TS_UPDATE_SYNC failed");
free_stream(s);
return 1;
}
}
-
- LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_send_data_update_sync");
free_stream(s);
return 0;
}
@@ -851,15 +895,14 @@ xrdp_rdp_incoming(struct xrdp_rdp *self)
struct xrdp_iso *iso;
iso = self->sec_layer->mcs_layer->iso_layer;
- LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_incoming");
-
if (xrdp_sec_incoming(self->sec_layer) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "xrdp_rdp_incoming: xrdp_sec_incoming failed");
return 1;
}
self->mcs_channel = self->sec_layer->mcs_layer->userid +
MCS_USERCHANNEL_BASE;
- LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_incoming mcs channel %d", self->mcs_channel);
+ LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp->mcs_channel %d", self->mcs_channel);
g_strncpy(self->client_info.client_addr, iso->trans->addr,
sizeof(self->client_info.client_addr) - 1);
g_strncpy(self->client_info.client_port, iso->trans->port,
@@ -889,14 +932,19 @@ xrdp_rdp_incoming(struct xrdp_rdp *self)
}
/*****************************************************************************/
+/* Process a [MS-RDPBCGR] TS_POINTER_PDU message */
static int
xrdp_rdp_process_data_pointer(struct xrdp_rdp *self, struct stream *s)
{
+ LOG_DEVEL(LOG_LEVEL_WARNING, "Protocol error ignored: a [MS-RDPBCGR] "
+ "TS_SHAREDATAHEADER PDUTYPE2_POINTER was received by the server "
+ "but this type of PDU is only suppose to be sent by the server "
+ "to the client.");
return 0;
}
/*****************************************************************************/
-/* RDP_DATA_PDU_INPUT */
+/* Process a [MS-RDPBCGR] TS_INPUT_PDU_DATA message */
static int
xrdp_rdp_process_data_input(struct xrdp_rdp *self, struct stream *s)
{
@@ -908,17 +956,18 @@ xrdp_rdp_process_data_input(struct xrdp_rdp *self, struct stream *s)
int param2;
int time;
- if (!s_check_rem(s, 4))
+ if (!s_check_rem_and_log(s, 4, "Parsing [MS-RDPBCGR] TS_INPUT_PDU_DATA"))
{
return 1;
}
in_uint16_le(s, num_events);
in_uint8s(s, 2); /* pad */
- LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_process_data_input %d events", num_events);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_INPUT_PDU_DATA "
+ "numEvents %d", num_events);
for (index = 0; index < num_events; index++)
{
- if (!s_check_rem(s, 12))
+ if (!s_check_rem_and_log(s, 12, "Parsing [MS-RDPBCGR] TS_INPUT_EVENT"))
{
return 1;
}
@@ -927,8 +976,38 @@ xrdp_rdp_process_data_input(struct xrdp_rdp *self, struct stream *s)
in_uint16_le(s, device_flags);
in_sint16_le(s, param1);
in_sint16_le(s, param2);
- LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data_input event %4.4x flags %4.4x param1 %d "
- "param2 %d time %d", msg_type, device_flags, param1, param2, time);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "With field [MS-RDPBCGR] TS_INPUT_EVENT "
+ "eventTime %d, messageType 0x%4.4x", time, msg_type);
+
+ switch (msg_type)
+ {
+ case RDP_INPUT_SYNCHRONIZE:
+ LOG_DEVEL(LOG_LEVEL_TRACE, "With field [MS-RDPBCGR] TS_INPUT_EVENT - TS_SYNC_EVENT "
+ "toggleFlags 0x%8.8x", ((param2 << 16) | param1));
+ break;
+ case RDP_INPUT_SCANCODE:
+ LOG_DEVEL(LOG_LEVEL_TRACE, "With field [MS-RDPBCGR] TS_INPUT_EVENT - TS_KEYBOARD_EVENT "
+ "keyboardFlags 0x%4.4x, keyCode %d", device_flags, param1);
+ break;
+ case RDP_INPUT_UNICODE:
+ LOG_DEVEL(LOG_LEVEL_TRACE, "With field [MS-RDPBCGR] TS_INPUT_EVENT - TS_UNICODE_KEYBOARD_EVENT "
+ "keyboardFlags 0x%4.4x, unicodeCode %d", device_flags, param1);
+ break;
+ case RDP_INPUT_MOUSE:
+ LOG_DEVEL(LOG_LEVEL_TRACE, "With field [MS-RDPBCGR] TS_INPUT_EVENT - TS_POINTER_EVENT "
+ "pointerFlags 0x%4.4x, xPos %d, yPos %d",
+ device_flags, param1, param2);
+ break;
+ case RDP_INPUT_MOUSEX:
+ LOG_DEVEL(LOG_LEVEL_TRACE, "With field [MS-RDPBCGR] TS_INPUT_EVENT - TS_POINTERX_EVENT "
+ "pointerFlags 0x%4.4x, xPos %d, yPos %d",
+ device_flags, param1, param2);
+ break;
+ default:
+ LOG_DEVEL(LOG_LEVEL_WARNING, "Received unknown [MS-RDPBCGR] TS_INPUT_EVENT "
+ "messageType 0x%4.4x", msg_type);
+ break;
+ }
if (self->session->callback != 0)
{
@@ -941,13 +1020,19 @@ xrdp_rdp_process_data_input(struct xrdp_rdp *self, struct stream *s)
self->session->callback(self->session->id, msg_type, param1, param2,
device_flags, time);
}
+ else
+ {
+ LOG_DEVEL(LOG_LEVEL_WARNING,
+ "Bug: no callback registered for xrdp_rdp_process_data_input");
+ }
}
- LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_process_data_input");
+ LOG_DEVEL(LOG_LEVEL_DEBUG, "Processing [MS-RDPBCGR] TS_INPUT_PDU_DATA complete");
return 0;
}
/*****************************************************************************/
+/* Send a [MS-RDPBCGR] TS_SYNCHRONIZE_PDU message */
static int
xrdp_rdp_send_synchronise(struct xrdp_rdp *self)
{
@@ -958,6 +1043,7 @@ xrdp_rdp_send_synchronise(struct xrdp_rdp *self)
if (xrdp_rdp_init_data(self, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "xrdp_rdp_send_synchronise: xrdp_rdp_init_data failed");
free_stream(s);
return 1;
}
@@ -965,9 +1051,12 @@ xrdp_rdp_send_synchronise(struct xrdp_rdp *self)
out_uint16_le(s, 1); /* messageType (2 bytes) */
out_uint16_le(s, 1002); /* targetUser (2 bytes) */
s_mark_end(s);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_SYNCHRONIZE_PDU "
+ "messageType 1, targetUser 1002");
if (xrdp_rdp_send_data(self, s, RDP_DATA_PDU_SYNCHRONISE) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "Sending [MS-RDPBCGR] TS_SYNCHRONIZE_PDU failed");
free_stream(s);
return 1;
}
@@ -977,6 +1066,7 @@ xrdp_rdp_send_synchronise(struct xrdp_rdp *self)
}
/*****************************************************************************/
+/* Send a [MS-RDPBCGR] TS_CONTROL_PDU message */
static int
xrdp_rdp_send_control(struct xrdp_rdp *self, int action)
{
@@ -987,6 +1077,7 @@ xrdp_rdp_send_control(struct xrdp_rdp *self, int action)
if (xrdp_rdp_init_data(self, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "xrdp_rdp_send_control: xrdp_rdp_init_data failed");
free_stream(s);
return 1;
}
@@ -995,9 +1086,12 @@ xrdp_rdp_send_control(struct xrdp_rdp *self, int action)
out_uint16_le(s, 0); /* userid */
out_uint32_le(s, 1002); /* control id */
s_mark_end(s);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_CONTROL_PDU "
+ "action %d, grantId 0, controlId 1002", action);
if (xrdp_rdp_send_data(self, s, RDP_DATA_PDU_CONTROL) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "Sending [MS-RDPBCGR] TS_CONTROL_PDU failed");
free_stream(s);
return 1;
}
@@ -1007,39 +1101,44 @@ xrdp_rdp_send_control(struct xrdp_rdp *self, int action)
}
/*****************************************************************************/
+/* Process a [MS-RDPBCGR] TS_CONTROL_PDU message */
static int
xrdp_rdp_process_data_control(struct xrdp_rdp *self, struct stream *s)
{
int action;
- LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data_control");
in_uint16_le(s, action);
in_uint8s(s, 2); /* user id */
in_uint8s(s, 4); /* control id */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_CONTROL_PDU "
+ "action 0x%4.4x, grantId (ignored), controlId (ignored)",
+ action);
if (action == RDP_CTL_REQUEST_CONTROL)
{
- LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data_control got RDP_CTL_REQUEST_CONTROL");
- LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data_control calling xrdp_rdp_send_synchronise");
+ LOG_DEVEL(LOG_LEVEL_DEBUG, "Responding to [MS-RDPBCGR] TS_CONTROL_PDU "
+ "action CTRLACTION_REQUEST_CONTROL with 3 messages: "
+ "TS_SYNCHRONIZE_PDU, TS_CONTROL_PDU with CTRLACTION_COOPERATE, "
+ " and TS_CONTROL_PDU with CTRLACTION_GRANTED_CONTROL");
xrdp_rdp_send_synchronise(self);
- LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data_control sending RDP_CTL_COOPERATE");
xrdp_rdp_send_control(self, RDP_CTL_COOPERATE);
- LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data_control sending RDP_CTL_GRANT_CONTROL");
xrdp_rdp_send_control(self, RDP_CTL_GRANT_CONTROL);
}
else
{
- LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data_control unknown action");
+ LOG_DEVEL(LOG_LEVEL_WARNING, "Received [MS-RDPBCGR] TS_CONTROL_PDU "
+ "action %d is unknown (skipped)", action);
}
return 0;
}
/*****************************************************************************/
+/* Process a [MS-RDPBCGR] TS_SYNCHRONIZE_PDU message */
static int
xrdp_rdp_process_data_sync(struct xrdp_rdp *self)
{
- LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data_sync");
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_SYNCHRONIZE_PDU - no-op");
return 0;
}
@@ -1057,16 +1156,17 @@ xrdp_rdp_process_screen_update(struct xrdp_rdp *self, struct stream *s)
int cx;
int cy;
- if (!s_check_rem(s, 4))
+ if (!s_check_rem_and_log(s, 4, "Parsing [MS-RDPBCGR] TS_REFRESH_RECT_PDU"))
{
return 1;
}
in_uint8(s, num_rects);
in_uint8s(s, 3); /* pad */
- LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_screen_update: num_rects %d", num_rects);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_REFRESH_RECT_PDU "
+ "numberOfAreas %d", num_rects);
for (index = 0; index < num_rects; index++)
{
- if (!s_check_rem(s, 8))
+ if (!s_check_rem_and_log(s, 8, "Parsing [MS-RDPBCGR] TS_RECTANGLE16"))
{
return 1;
}
@@ -1075,7 +1175,8 @@ xrdp_rdp_process_screen_update(struct xrdp_rdp *self, struct stream *s)
in_uint16_le(s, top);
in_uint16_le(s, right);
in_uint16_le(s, bottom);
- LOG_DEVEL(LOG_LEVEL_TRACE, " left %d top %d right %d bottom %d",
+ LOG_DEVEL(LOG_LEVEL_TRACE, "With field [MS-RDPBCGR] TS_RECTANGLE16 "
+ "left %d, top %d, right %d, bottom %d",
left, top, right, bottom);
cx = (right - left) + 1;
cy = (bottom - top) + 1;
@@ -1084,11 +1185,17 @@ xrdp_rdp_process_screen_update(struct xrdp_rdp *self, struct stream *s)
self->session->callback(self->session->id, 0x4444,
left, top, cx, cy);
}
+ else
+ {
+ LOG_DEVEL(LOG_LEVEL_WARNING,
+ "Bug: no callback registered for xrdp_rdp_process_screen_update");
+ }
}
return 0;
}
/*****************************************************************************/
+/* Send a [MS-RDPBCGR] TS_FONT_MAP_PDU message */
static int
xrdp_rdp_send_fontmap(struct xrdp_rdp *self)
{
@@ -1099,6 +1206,8 @@ xrdp_rdp_send_fontmap(struct xrdp_rdp *self)
if (xrdp_rdp_init_data(self, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "xrdp_rdp_send_fontmap: xrdp_rdp_init_data failed");
free_stream(s);
return 1;
}
@@ -1109,9 +1218,13 @@ xrdp_rdp_send_fontmap(struct xrdp_rdp *self)
out_uint16_le(s, 0x4); /* entrySize */
s_mark_end(s);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_FONT_MAP_PDU "
+ "numberEntries 0, totalNumEntries 0, mapFlags 0x0003, entrySize 4");
if (xrdp_rdp_send_data(self, s, 0x28) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "Sending [MS-RDPBCGR] TS_FONT_MAP_PDU failed");
free_stream(s);
return 1;
}
@@ -1121,37 +1234,51 @@ xrdp_rdp_send_fontmap(struct xrdp_rdp *self)
}
/*****************************************************************************/
+/* Process a [MS-RDPBCGR] TS_FONT_LIST_PDU message */
static int
xrdp_rdp_process_data_font(struct xrdp_rdp *self, struct stream *s)
{
int seq;
- LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_process_data_font");
+ if (!s_check_rem_and_log(s, 6, "Parsing [MS-RDPBCGR] TS_FONT_LIST_PDU"))
+ {
+ return 1;
+ }
+
in_uint8s(s, 2); /* NumberFonts: 0x0, SHOULD be set to 0 */
in_uint8s(s, 2); /* TotalNumberFonts: 0x0, SHOULD be set to 0 */
in_uint16_le(s, seq); /* ListFlags */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_FONT_LIST_PDU "
+ "numberFonts (ignored), totalNumFonts (ignored), listFlags 0x%4.4x",
+ seq);
/* 419 client sends Seq 1, then 2 */
/* 2600 clients sends only Seq 3 */
+ /* listFlags SHOULD be set to 0x0003, which is the logical OR'd value of
+ FONTLIST_FIRST (0x0001) and FONTLIST_LAST (0x0002) */
if (seq == 2 || seq == 3) /* after second font message, we are up and */
{
/* running */
- LOG_DEVEL(LOG_LEVEL_TRACE, "sending fontmap");
+ LOG_DEVEL(LOG_LEVEL_DEBUG,
+ "Client sent FONTLIST_LAST, replying with server fontmap");
xrdp_rdp_send_fontmap(self);
self->session->up_and_running = 1;
- LOG_DEVEL(LOG_LEVEL_TRACE, "yeah, up_and_running");
- LOG_DEVEL(LOG_LEVEL_TRACE, "up_and_running set");
+ LOG_DEVEL(LOG_LEVEL_INFO, "yeah, up_and_running");
xrdp_rdp_send_data_update_sync(self);
xrdp_channel_drdynvc_start(self->sec_layer->chan_layer);
}
+ else
+ {
+ LOG_DEVEL(LOG_LEVEL_DEBUG, "Received [MS-RDPBCGR] TS_FONT_LIST_PDU "
+ "without FONTLIST_LAST in the listFlags field. Ignoring message.");
+ }
- LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_process_data_font");
return 0;
}
/*****************************************************************************/
-/* sent 37 pdu */
+/* Send a Sending [MS-RDPBCGR] TS_SHUTDOWN_DENIED_PDU message */
static int
xrdp_rdp_send_disconnect_query_response(struct xrdp_rdp *self)
{
@@ -1162,14 +1289,19 @@ xrdp_rdp_send_disconnect_query_response(struct xrdp_rdp *self)
if (xrdp_rdp_init_data(self, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "xrdp_rdp_send_disconnect_query_response: xrdp_rdp_init_data failed");
free_stream(s);
return 1;
}
s_mark_end(s);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_SHUTDOWN_DENIED_PDU");
- if (xrdp_rdp_send_data(self, s, 37) != 0)
+ if (xrdp_rdp_send_data(self, s, PDUTYPE2_SHUTDOWN_DENIED) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "Sending [MS-RDPBCGR] TS_SHUTDOWN_DENIED_PDU failed");
free_stream(s);
return 1;
}
@@ -1180,7 +1312,7 @@ xrdp_rdp_send_disconnect_query_response(struct xrdp_rdp *self)
#if 0 /* not used */
/*****************************************************************************/
-/* sent RDP_DATA_PDU_DISCONNECT 47 pdu */
+/* Send a [MS-RDPBCGR] TS_SET_ERROR_INFO_PDU message */
static int
xrdp_rdp_send_disconnect_reason(struct xrdp_rdp *self, int reason)
{
@@ -1191,15 +1323,21 @@ xrdp_rdp_send_disconnect_reason(struct xrdp_rdp *self, int reason)
if (xrdp_rdp_init_data(self, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "xrdp_rdp_send_disconnect_reason: xrdp_rdp_init_data failed");
free_stream(s);
return 1;
}
out_uint32_le(s, reason);
s_mark_end(s);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_SET_ERROR_INFO_PDU "
+ "errorInfo 0x%8.8x", reason);
if (xrdp_rdp_send_data(self, s, RDP_DATA_PDU_DISCONNECT) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "Sending [MS-RDPBCGR] TS_SET_ERROR_INFO_PDU failed");
free_stream(s);
return 1;
}
@@ -1210,24 +1348,35 @@ xrdp_rdp_send_disconnect_reason(struct xrdp_rdp *self, int reason)
#endif
/*****************************************************************************/
+/* Process a [MS-RDPRFX] TS_FRAME_ACKNOWLEDGE_PDU message */
static int
xrdp_rdp_process_frame_ack(struct xrdp_rdp *self, struct stream *s)
{
int frame_id;
- LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_frame_ack:");
+ if (!s_check_rem_and_log(s, 4, "Parsing [MS-RDPRFX] TS_FRAME_ACKNOWLEDGE_PDU"))
+ {
+ return 1;
+ }
in_uint32_le(s, frame_id);
- LOG_DEVEL(LOG_LEVEL_TRACE, " frame_id %d", frame_id);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPRFX] TS_FRAME_ACKNOWLEDGE_PDU "
+ "frameID %d", frame_id);
if (self->session->callback != 0)
{
/* call to xrdp_wm.c : callback */
self->session->callback(self->session->id, 0x5557, frame_id, 0,
0, 0);
}
+ else
+ {
+ LOG_DEVEL(LOG_LEVEL_WARNING,
+ "Bug: no callback registered for xrdp_rdp_process_frame_ack");
+ }
return 0;
}
/*****************************************************************************/
+/* Process a [MS-RDPBCGR] TS_SUPPRESS_OUTPUT_PDU message */
static int
xrdp_rdp_process_suppress(struct xrdp_rdp *self, struct stream *s)
{
@@ -1237,28 +1386,33 @@ xrdp_rdp_process_suppress(struct xrdp_rdp *self, struct stream *s)
int right;
int bottom;
- if (!s_check_rem(s, 1))
+ if (!s_check_rem_and_log(s, 1, "Parsing [MS-RDPBCGR] TS_SUPPRESS_OUTPUT_PDU"))
{
return 1;
}
in_uint8(s, allowDisplayUpdates);
- LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_suppress: allowDisplayUpdates %d bytes "
- "left %d", allowDisplayUpdates, (int) (s->end - s->p));
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_SUPPRESS_OUTPUT_PDU "
+ "allowDisplayUpdates %d", allowDisplayUpdates);
switch (allowDisplayUpdates)
{
case 0: /* SUPPRESS_DISPLAY_UPDATES */
self->client_info.suppress_output = 1;
- LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_suppress: suppress_output %d",
- self->client_info.suppress_output);
+ LOG_DEVEL(LOG_LEVEL_DEBUG, "Client requested display output to be suppressed");
if (self->session->callback != 0)
{
self->session->callback(self->session->id, 0x5559, 1,
0, 0, 0);
}
+ else
+ {
+ LOG_DEVEL(LOG_LEVEL_WARNING,
+ "Bug: no callback registered for xrdp_rdp_process_suppress");
+ }
break;
case 1: /* ALLOW_DISPLAY_UPDATES */
self->client_info.suppress_output = 0;
- if (!s_check_rem(s, 11))
+ LOG_DEVEL(LOG_LEVEL_DEBUG, "Client requested display output to be enabled");
+ if (!s_check_rem_and_log(s, 11, "Parsing [MS-RDPBCGR] Padding and TS_RECTANGLE16"))
{
return 1;
}
@@ -1267,9 +1421,8 @@ xrdp_rdp_process_suppress(struct xrdp_rdp *self, struct stream *s)
in_uint16_le(s, top);
in_uint16_le(s, right);
in_uint16_le(s, bottom);
- LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_suppress: suppress_output %d "
- "left %d top %d right %d bottom %d",
- self->client_info.suppress_output,
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_RECTANGLE16 "
+ "left %d, top %d, right %d, bottom %d",
left, top, right, bottom);
if (self->session->callback != 0)
{
@@ -1277,13 +1430,18 @@ xrdp_rdp_process_suppress(struct xrdp_rdp *self, struct stream *s)
MAKELONG(left, top),
MAKELONG(right, bottom), 0);
}
+ else
+ {
+ LOG_DEVEL(LOG_LEVEL_WARNING,
+ "Bug: no callback registered for xrdp_rdp_process_suppress");
+ }
break;
}
return 0;
}
/*****************************************************************************/
-/* RDP_PDU_DATA */
+/* Process a [MS-RDPBCGR] TS_SHAREDATAHEADER message based on it's pduType2 */
int
xrdp_rdp_process_data(struct xrdp_rdp *self, struct stream *s)
{
@@ -1292,25 +1450,36 @@ xrdp_rdp_process_data(struct xrdp_rdp *self, struct stream *s)
int compressedType;
int compressedLength;
- if (!s_check_rem(s, 12))
+ if (!s_check_rem_and_log(s, 12, "Parsing [MS-RDPBCGR] TS_SHAREDATAHEADER"))
{
return 1;
}
- in_uint8s(s, 6);
- in_uint16_le(s, uncompressedLength);
+ in_uint8s(s, 6); /* shareID (4 bytes), padding (1 byte), streamID (1 byte) */
+ in_uint16_le(s, uncompressedLength); /* shareID */
in_uint8(s, pduType2);
in_uint8(s, compressedType);
in_uint16_le(s, compressedLength);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_SHAREDATAHEADER "
+ "shareID (ignored), streamID (ignored), uncompressedLength %d, "
+ "pduType2 0x%2.2x, compressedType 0x%2.2x, compressedLength %d",
+ uncompressedLength, pduType2, compressedType, compressedLength);
+
if (compressedType != 0)
{
/* don't support compression */
+ /* PACKET_COMPR_TYPE_8K = 0x00 */
+ LOG(LOG_LEVEL_ERROR, "Only RDP 4.0 bulk compression "
+ "(PACKET_COMPR_TYPE_8K) is supported by XRDP");
return 1;
}
if (compressedLength > uncompressedLength)
{
+ LOG(LOG_LEVEL_ERROR, "The compressed length %d is larger than "
+ "the uncompressed length %d, failing the processing of this "
+ "PDU", compressedLength, uncompressedLength);
return 1;
}
- LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data pduType2 %d", pduType2);
+
switch (pduType2)
{
case RDP_DATA_PDU_POINTER: /* 27(0x1b) */
@@ -1328,13 +1497,14 @@ xrdp_rdp_process_data(struct xrdp_rdp *self, struct stream *s)
case PDUTYPE2_REFRESH_RECT:
xrdp_rdp_process_screen_update(self, s);
break;
- case 35: /* 35(0x23) PDUTYPE2_SUPPRESS_OUTPUT */
+ case PDUTYPE2_SUPPRESS_OUTPUT: /* 35(0x23) */
xrdp_rdp_process_suppress(self, s);
break;
- case 36: /* 36(0x24) ?? disconnect query? */
+ case PDUTYPE2_SHUTDOWN_REQUEST: /* 36(0x24) ?? disconnect query? */
/* when this message comes, send a 37 back so the client */
/* is sure the connection is alive and it can ask if user */
/* really wants to disconnect */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_SHUTDOWN_REQ_PDU");
xrdp_rdp_send_disconnect_query_response(self); /* send a 37 back */
break;
case RDP_DATA_PDU_FONT2: /* 39(0x27) */
@@ -1344,7 +1514,9 @@ xrdp_rdp_process_data(struct xrdp_rdp *self, struct stream *s)
xrdp_rdp_process_frame_ack(self, s);
break;
default:
- LOG_DEVEL(LOG_LEVEL_TRACE, "unknown in xrdp_rdp_process_data pduType2 %d", pduType2);
+ LOG(LOG_LEVEL_WARNING,
+ "Received unknown [MS-RDPBCGR] TS_SHAREDATAHEADER pduType2 %d (ignoring)",
+ pduType2);
break;
}
return 0;
@@ -1353,12 +1525,7 @@ xrdp_rdp_process_data(struct xrdp_rdp *self, struct stream *s)
int
xrdp_rdp_disconnect(struct xrdp_rdp *self)
{
- int rv;
-
- LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_disconnect");
- rv = xrdp_sec_disconnect(self->sec_layer);
- LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_disconnect");
- return rv;
+ return xrdp_sec_disconnect(self->sec_layer);
}
/*****************************************************************************/
@@ -1367,62 +1534,85 @@ xrdp_rdp_send_deactivate(struct xrdp_rdp *self)
{
struct stream *s;
- LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_send_deactivate");
make_stream(s);
init_stream(s, 8192);
if (xrdp_rdp_init(self, s) != 0)
{
free_stream(s);
- LOG(LOG_LEVEL_ERROR, "out xrdp_rdp_send_deactivate error");
+ LOG(LOG_LEVEL_ERROR, "xrdp_rdp_send_deactivate: xrdp_rdp_init failed");
return 1;
}
+ /* TODO: why are all the fields missing from the TS_DEACTIVATE_ALL_PDU? */
s_mark_end(s);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_DEACTIVATE_ALL_PDU "
+ "shareID <not set>, lengthSourceDescriptor <not set>, "
+ "sourceDescriptor <not set>");
if (xrdp_rdp_send(self, s, PDUTYPE_DEACTIVATEALLPDU) != 0)
{
free_stream(s);
- LOG(LOG_LEVEL_ERROR, "out xrdp_rdp_send_deactivate error");
+ LOG(LOG_LEVEL_ERROR, "Sending [MS-RDPBCGR] TS_DEACTIVATE_ALL_PDU failed");
return 1;
}
free_stream(s);
- LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_send_deactivate");
return 0;
}
/*****************************************************************************/
+/** Send a [MS-RDPBCGR] TS_SAVE_SESSION_INFO_PDU_DATA message.
+ *
+ * @param self
+ * @param data the data to send to the client in the
+ * TS_SAVE_SESSION_INFO_PDU_DATA message. The first 4 bytes of the data
+ * buffer MUST by the infoType value as specified in MS-RDPBCGR 2.2.10.1.1
+ * @param data_bytes the length of the data buffer
+ * @returns error code
+ */
int
xrdp_rdp_send_session_info(struct xrdp_rdp *self, const char *data,
int data_bytes)
{
struct stream *s;
- LOG_DEVEL(LOG_LEVEL_INFO, "xrdp_rdp_send_session_info: data_bytes %d", data_bytes);
+ if (data == NULL)
+ {
+ LOG(LOG_LEVEL_ERROR, "data must not be null");
+ return 1;
+ }
+ if (data_bytes < 4)
+ {
+ LOG(LOG_LEVEL_ERROR, "data_bytes must greater than or equal to 4");
+ return 1;
+ }
+
make_stream(s);
init_stream(s, 8192);
if (xrdp_rdp_init_data(self, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "xrdp_rdp_send_session_info: xrdp_rdp_init_data failed");
free_stream(s);
return 1;
}
- if (s_check_rem_out(s, data_bytes))
- {
- out_uint8a(s, data, data_bytes);
- }
- else
+ if (!s_check_rem_out_and_log(s, data_bytes, "Sending [MS-RDPBCGR] TS_SAVE_SESSION_INFO_PDU_DATA"))
{
free_stream(s);
return 1;
}
+ out_uint8a(s, data, data_bytes);
s_mark_end(s);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_SAVE_SESSION_INFO_PDU_DATA "
+ "infoType 0x%8.8x, infoData <omitted from log>",
+ *((unsigned int *) data));
if (xrdp_rdp_send_data(self, s, RDP_DATA_PDU_LOGON) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "Sending [MS-RDPBCGR] TS_SAVE_SESSION_INFO_PDU_DATA failed");
free_stream(s);
return 1;
}
diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c
index e632ca36..7fdf3fc8 100644
--- a/libxrdp/xrdp_sec.c
+++ b/libxrdp/xrdp_sec.c
@@ -45,28 +45,94 @@ static tui8 g_pad_92[48] =
92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92
};
+
+/*****************************************************************************/
+/* Licensing request v2 PDU
+ *
+ * [MS-RDPBCGR] TS_SECURITY_HEADER - Basic
+ * [MS-RDPELE] SERVER_LICENSE_REQUEST with PREAMBLE_VERSION_2_0
+ */
/* some compilers need unsigned char to avoid warnings */
static tui8 g_lic1[322] =
{
+ /* [MS-RDPBCGR] TS_SECURITY_HEADER - Basic
+ * flags (2) = 0x0080 (SEC_LICENSE_PKT)
+ * flagsHi (2) = unused (arbitrary data)
+ * [MS-RDPBCGR] LICENSE_PREAMBLE
+ * bMsgType (1) = 0x01 (LICENSE_REQUEST)
+ * flags (1) = 0x02 (PREAMBLE_VERSION_2_0)
+ * wMsgSize (2) = 318 (excludes the 4 bytes TS_SECURITY_HEADER Basic)
+ */
0x80, 0x00, 0x3e, 0x01, 0x01, 0x02, 0x3e, 0x01,
+ /* [MS-RDPELE] SERVER_LICENSE_REQUEST
+ * ServerRandom (32) = <see hex below>
+ */
0x7b, 0x3c, 0x31, 0xa6, 0xae, 0xe8, 0x74, 0xf6,
0xb4, 0xa5, 0x03, 0x90, 0xe7, 0xc2, 0xc7, 0x39,
0xba, 0x53, 0x1c, 0x30, 0x54, 0x6e, 0x90, 0x05,
0xd0, 0x05, 0xce, 0x44, 0x18, 0x91, 0x83, 0x81,
+ /* [MS-RDPELE] SERVER_LICENSE_REQUEST - ProductInfo
+ * [MS-RDPELE] PRODUCT_INFO
+ * dwVersion (4) = 0x00040000
+ * cbCompanyName (4) = 0x0000002c (44)
+ */
0x00, 0x00, 0x04, 0x00, 0x2c, 0x00, 0x00, 0x00,
+ /*
+ * pbCompanyName (44) = UTF-16("Microsoft Corporation")
+ * cbProductId (4) = 0x00000008 (8)
+ */
0x4d, 0x00, 0x69, 0x00, 0x63, 0x00, 0x72, 0x00,
0x6f, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x66, 0x00,
0x74, 0x00, 0x20, 0x00, 0x43, 0x00, 0x6f, 0x00,
0x72, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x72, 0x00,
0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00,
0x6e, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ /*
+ * pbProductId (8) = UTF-16("236")
+ */
0x32, 0x00, 0x33, 0x00, 0x36, 0x00, 0x00, 0x00,
+ /* [MS-RDPELE] SERVER_LICENSE_REQUEST - KeyExchangeList
+ * [MS-RDPBCGR] LICENSE_BINARY_BLOB
+ * wBlobType (2) = 0x000d (BB_KEY_EXCHG_ALG_BLOB)
+ * wBlobLen (2) = 0x0004 (4)
+ * blobData (4) = 0x00000001 (KEY_EXCHANGE_ALG_RSA)
+ */
0x0d, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00,
+ /* [MS-RDPELE] SERVER_LICENSE_REQUEST - ServerCertificate
+ * [MS-RDPBCGR] LICENSE_BINARY_BLOB
+ * wBlobType (2) = BB_CERTIFICATE_BLOB (0x0003)
+ * wBlobLen (2) = 0x00b8 (184)
+ * blobData = <SERVER_CERTIFICATE>
+ *
+ * [MS-RDPBCGR] SERVER_CERTIFICATE
+ * dwVersion (31 bits) = 0x00000001 (CERT_CHAIN_VERSION_1)
+ * t (1 bit) = 0 (temporary certificate)
+ */
0x03, 0x00, 0xb8, 0x00, 0x01, 0x00, 0x00, 0x00,
+ /*
+ * certData = <PROPRIETARYSERVERCERTIFICATE>
+ *
+ * [MS-RDPBCGR] PROPRIETARYSERVERCERTIFICATE
+ * dwSigAlgId (4) = 0x00000001 (SIGNATURE_ALG_RSA)
+ * dwKeyAlgId (4) = 0x00000001 (KEY_EXCHANGE_ALG_RSA)
+ * wPublicKeyBlobType (2) = 0x0006 (BB_RSA_KEY_BLOB)
+ * wPublicKeyBlobLen (2) = 0x005c (92)
+ * PublicKeyBlob = <RSA_PUBLIC_KEY>
+ *
+ * [MS-RDPBCGR] RSA_PUBLIC_KEY
+ * magic (4) = 0x31415352
+ * keylen (4) = 0x00000048 (72)
+ * bitlen (4) = 0x00000200 (512)
+ * datalen (4) = 0x0000003f (63)
+ * pubExp (4) = 0x00010001 (65537)
+ */
0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x06, 0x00, 0x5c, 0x00, 0x52, 0x53, 0x41, 0x31,
0x48, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
0x3f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
+ /*
+ * modulus (72) = <see hex below>
+ */
0x01, 0xc7, 0xc9, 0xf7, 0x8e, 0x5a, 0x38, 0xe4,
0x29, 0xc3, 0x00, 0x95, 0x2d, 0xdd, 0x4c, 0x3e,
0x50, 0x45, 0x0b, 0x0d, 0x9e, 0x2a, 0x5d, 0x18,
@@ -76,6 +142,14 @@ static tui8 g_lic1[322] =
0xc8, 0xc7, 0xb4, 0xa8, 0x47, 0xc8, 0x50, 0x71,
0x74, 0x29, 0x53, 0x89, 0x6d, 0x9c, 0xed, 0x70,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* [MS-RDPELE] SERVER_LICENSE_REQUEST - ServerCertificate
+ * [MS-RDPBCGR] LICENSE_BINARY_BLOB - blobData
+ * [MS-RDPBCGR] SERVER_CERTIFICATE - certData
+ * [MS-RDPBCGR] PROPRIETARYSERVERCERTIFICATE
+ * wSignatureBlobType (2) = 0x0008 (BB_RSA_SIGNATURE_BLOB)
+ * wSignatureBlobLen (2) = 0x0048 (72)
+ * SignatureBlob (72) = <see hex below, calculated using [MS-RDPBCGR] 5.3.3.1.2>
+ */
0x08, 0x00, 0x48, 0x00, 0xa8, 0xf4, 0x31, 0xb9,
0xab, 0x4b, 0xe6, 0xb4, 0xf4, 0x39, 0x89, 0xd6,
0xb1, 0xda, 0xf6, 0x1e, 0xec, 0xb1, 0xf0, 0x54,
@@ -85,26 +159,90 @@ static tui8 g_lic1[322] =
0xcb, 0x11, 0xc3, 0xf2, 0xdb, 0x09, 0x42, 0x68,
0x29, 0x56, 0x58, 0x01, 0x56, 0xdb, 0x59, 0x03,
0x69, 0xdb, 0x7d, 0x37, 0x00, 0x00, 0x00, 0x00,
+ /* <last 4 bytes of SignatureBlob>
+ *
+ * [MS-RDPELE] SERVER_LICENSE_REQUEST - ScopeList
+ * [MS-RDPELE] SCOPE_LIST
+ * ScopeCount (4) = 0x00000001 (1)
+ * ScopeArray = <LICENSE_BINARY_BLOB>
+ *
+ * [MS-RDPBCGR] LICENSE_BINARY_BLOB
+ * wBlobType (2) = 0x000e (BB_SCOPE_BLOB)
+ * wBlobLen (2) = 0x000e (14)
+ * blobData (14) = ISO-8859-1("microsoft.com")
+ */
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x0e, 0x00, 0x0e, 0x00, 0x6d, 0x69, 0x63, 0x72,
0x6f, 0x73, 0x6f, 0x66, 0x74, 0x2e, 0x63, 0x6f,
0x6d, 0x00
};
+/*****************************************************************************/
+/* Licensing success response v2 PDU
+ *
+ * [MS-RDPBCGR] TS_SECURITY_HEADER - Basic
+ * [MS-RDPELE] LICENSE_ERROR_MESSAGE with STATUS_VALID_CLIENT
+ */
/* some compilers need unsigned char to avoid warnings */
static tui8 g_lic2[20] =
{
+ /* [MS-RDPBCGR] TS_SECURITY_HEADER - Basic
+ * flags (2) = 0x0080 (SEC_LICENSE_PKT)
+ * flagsHi (2) = unused (arbitrary data)
+ * [MS-RDPBCGR] LICENSE_PREAMBLE
+ * bMsgType (1) = 0xff (ERROR_ALERT)
+ * flags (1) = 0x02 (PREAMBLE_VERSION_2_0)
+ * wMsgSize (2) = 0x10 (16, excludes the 4 bytes TS_SECURITY_HEADER Basic)
+ */
0x80, 0x00, 0x10, 0x00, 0xff, 0x02, 0x10, 0x00,
+ /*
+ * [MS-RDPBCGR] LICENSE_ERROR_MESSAGE
+ * dwErrorCode (4) = 0x00000007 (STATUS_VALID_CLIENT)
+ * dwStateTransition (4) = 0x00000002 (ST_NO_TRANSITION)
+ * bbErrorInfo = <LICENSE_BINARY_BLOB>
+ */
0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ /*
+ * [MS-RDPBCGR] LICENSE_BINARY_BLOB
+ * wBlobType (2) = 0x1428 <ignored by client> (should be 0x0004 BB_ERROR_BLOB)
+ * wBlobLen (2) = 0x0000 (0)
+ */
0x28, 0x14, 0x00, 0x00
};
-/* mce */
+/*****************************************************************************/
+/* Licensing success response v3 PDU
+ *
+ * [MS-RDPBCGR] TS_SECURITY_HEADER - Basic
+ * [MS-RDPELE] LICENSE_ERROR_MESSAGE with STATUS_VALID_CLIENT
+ *
+ * used for Media Center Edition
+ */
/* some compilers need unsigned char to avoid warnings */
static tui8 g_lic3[20] =
{
+ /* S */
+ /* [MS-RDPBCGR] TS_SECURITY_HEADER - Basic
+ * flags (2) = 0x0280 (SEC_LICENSE_PKT | SEC_LICENSE_ENCRYPT_CS)
+ * flagsHi (2) = unused (arbitrary data)
+ * [MS-RDPBCGR] LICENSE_PREAMBLE
+ * bMsgType (1) = 0xff (ERROR_ALERT)
+ * flags (1) = 0x03 (PREAMBLE_VERSION_3_0)
+ * wMsgSize (2) = 0x0010 (16, excludes the 4 bytes TS_SECURITY_HEADER Basic)
+ */
0x80, 0x02, 0x10, 0x00, 0xff, 0x03, 0x10, 0x00,
+ /*
+ * [MS-RDPBCGR] LICENSE_ERROR_MESSAGE
+ * dwErrorCode (4) = 0x00000007 (STATUS_VALID_CLIENT)
+ * dwStateTransition (4) = 0x00000002 (ST_NO_TRANSITION)
+ * bbErrorInfo = <LICENSE_BINARY_BLOB>
+ */
0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ /*
+ * [MS-RDPBCGR] LICENSE_BINARY_BLOB
+ * wBlobType (2) = 0x99f3 <ignored by client> (should be 0x0004 BB_ERROR_BLOB)
+ * wBlobLen (2) = 0x0000 (0)
+ */
0xf3, 0x99, 0x00, 0x00
};
@@ -441,7 +579,6 @@ xrdp_sec_create(struct xrdp_rdp *owner, struct trans *trans)
{
struct xrdp_sec *self;
- LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_sec_create");
self = (struct xrdp_sec *) g_malloc(sizeof(struct xrdp_sec), 1);
self->rdp_layer = owner;
self->crypt_method = CRYPT_METHOD_NONE; /* set later */
@@ -451,7 +588,6 @@ xrdp_sec_create(struct xrdp_rdp *owner, struct trans *trans)
self->fastpath_layer = xrdp_fastpath_create(self, trans);
self->chan_layer = xrdp_channel_create(self, self->mcs_layer);
self->is_security_header_present = 1;
- LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_create");
return self;
}
@@ -462,7 +598,6 @@ xrdp_sec_delete(struct xrdp_sec *self)
{
if (self == 0)
{
- LOG(LOG_LEVEL_ERROR, "xrdp_sec_delete: self is null");
return;
}
@@ -488,6 +623,7 @@ xrdp_sec_init(struct xrdp_sec *self, struct stream *s)
{
if (xrdp_mcs_init(self->mcs_layer, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "xrdp_sec_init: xrdp_mcs_init failed");
return 1;
}
@@ -614,6 +750,7 @@ xrdp_sec_encrypt(struct xrdp_sec *self, char *data, int len)
/*****************************************************************************
* convert utf-16 encoded string from stream into utf-8 string.
* note: src_bytes doesn't include the null-terminator char.
+ * Copied From: xrdp_sec.c
*/
static int
unicode_utf16_in(struct stream *s, int src_bytes, char *dst, int dst_len)
@@ -623,13 +760,14 @@ unicode_utf16_in(struct stream *s, int src_bytes, char *dst, int dst_len)
int i;
int bytes;
- LOG_DEVEL(LOG_LEVEL_DEBUG, "unicode_utf16_in: uni_len %d, dst_len %d", src_bytes, dst_len);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "unicode_utf16_in: uni_len %d, dst_len %d", src_bytes, dst_len);
if (src_bytes == 0)
{
- if (!s_check_rem(s, 2))
+ if (!s_check_rem_and_log(s, 2, "Parsing UTF-16"))
{
return 1;
}
+ LOG_DEVEL(LOG_LEVEL_TRACE, "unicode_utf16_in: num_chars 0, dst '' (empty string)");
in_uint8s(s, 2); /* null terminator */
return 0;
}
@@ -638,7 +776,7 @@ unicode_utf16_in(struct stream *s, int src_bytes, char *dst, int dst_len)
src = g_new0(twchar, bytes);
for (i = 0; i < bytes / 2; ++i)
{
- if (!s_check_rem(s, 2))
+ if (!s_check_rem_and_log(s, 2, "Parsing UTF-16"))
{
g_free(src);
return 1;
@@ -650,13 +788,14 @@ unicode_utf16_in(struct stream *s, int src_bytes, char *dst, int dst_len)
{
g_memset(dst, '\0', dst_len);
}
- LOG_DEVEL(LOG_LEVEL_DEBUG, "unicode_utf16_in: num_chars %d, dst %s", num_chars, dst);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "unicode_utf16_in: num_chars %d, dst '%s'", num_chars, dst);
g_free(src);
return 0;
}
/*****************************************************************************/
+/* Process TS_INFO_PACKET */
/* returns error */
static int
xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
@@ -674,57 +813,73 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
/* initialize (zero out) local variables */
g_memset(tmpdata, 0, sizeof(char) * 256);
- if (!s_check_rem(s, 8))
+ if (!s_check_rem_and_log(s, 8, "Parsing [MS-RDPBCGR] TS_INFO_PACKET"))
{
return 1;
}
in_uint8s(s, 4);
in_uint32_le(s, flags);
- LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_sec_process_logon_info flags $%x", flags);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Parsing [MS-RDPBCGR] TS_INFO_PACKET");
/* this is the first test that the decrypt is working */
if ((flags & RDP_LOGON_NORMAL) != RDP_LOGON_NORMAL) /* 0x33 */
{
/* must be or error */
- LOG(LOG_LEVEL_ERROR, "xrdp_sec_process_logon_info: flags wrong, likely decrypt "
- "not working");
+ LOG(LOG_LEVEL_ERROR, "received wrong flags, likely decrypt not working");
return 1;
}
if (flags & RDP_LOGON_LEAVE_AUDIO)
{
self->rdp_layer->client_info.sound_code = 1;
- LOG_DEVEL(LOG_LEVEL_TRACE, "flag RDP_LOGON_LEAVE_AUDIO found");
+ LOG_DEVEL(LOG_LEVEL_DEBUG, "[MS-RDPBCGR] TS_INFO_PACKET flag INFO_REMOTECONSOLEAUDIO found");
+ LOG(LOG_LEVEL_DEBUG,
+ "Client requested that audio on the server be played on the server.");
}
if (flags & RDP_LOGON_RAIL)
{
self->rdp_layer->client_info.rail_enable = 1;
- LOG_DEVEL(LOG_LEVEL_TRACE, "flag RDP_LOGON_RAIL found");
+ LOG_DEVEL(LOG_LEVEL_DEBUG, "[MS-RDPBCGR] TS_INFO_PACKET flag INFO_RAIL found");
+ LOG(LOG_LEVEL_DEBUG,
+ "Client requested Remote Application Integrated Locally (RAIL).");
}
- if ((flags & RDP_LOGON_AUTO) && (!self->rdp_layer->client_info.is_mce))
- /* todo, for now not allowing autologon and mce both */
+ if (flags & RDP_LOGON_AUTO)
{
- self->rdp_layer->client_info.rdp_autologin = 1;
- LOG_DEVEL(LOG_LEVEL_TRACE, "flag RDP_LOGON_AUTO found");
+ LOG_DEVEL(LOG_LEVEL_DEBUG, "[MS-RDPBCGR] TS_INFO_PACKET flag INFO_AUTOLOGON found");
+ /* todo, for now not allowing autologon and mce both */
+ if (!self->rdp_layer->client_info.is_mce)
+ {
+ self->rdp_layer->client_info.rdp_autologin = 1;
+ LOG(LOG_LEVEL_DEBUG, "Client requested auto logon.");
+ }
+ else
+ {
+ LOG(LOG_LEVEL_WARNING, "Auto logon is not supported with MCE");
+ }
}
if (flags & RDP_COMPRESSION)
{
- LOG_DEVEL(LOG_LEVEL_TRACE, "flag RDP_COMPRESSION found");
+ LOG_DEVEL(LOG_LEVEL_DEBUG, "[MS-RDPBCGR] TS_INFO_PACKET flag INFO_COMPRESSION found, "
+ "CompressionType 0x%1.1x", (flags & 0x00001E00) >> 9);
+ /* TODO: check the client's supported compression type vs the server
+ compression used */
if (self->rdp_layer->client_info.use_bulk_comp)
{
- LOG_DEVEL(LOG_LEVEL_TRACE, "flag RDP_COMPRESSION set");
+
self->rdp_layer->client_info.rdp_compression = 1;
+ LOG(LOG_LEVEL_DEBUG, "Client requested compression enabled.");
}
else
{
- LOG_DEVEL(LOG_LEVEL_TRACE, "flag RDP_COMPRESSION not set");
+ LOG(LOG_LEVEL_DEBUG, "Client requested compression, but server "
+ "compression is disabled.");
}
}
- if (!s_check_rem(s, 2))
+ if (!s_check_rem_and_log(s, 2, "Parsing [MS-RDPBCGR] TS_INFO_PACKET cbDomain"))
{
return 1;
}
@@ -732,11 +887,13 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
if (len_domain >= INFO_CLIENT_MAX_CB_LEN)
{
- LOG(LOG_LEVEL_ERROR, "ERROR [xrdp_sec_process_logon_info()]: len_domain >= %d", INFO_CLIENT_MAX_CB_LEN);
+ LOG(LOG_LEVEL_ERROR,
+ "Client supplied domain is too long. Max length %d, domain length %d",
+ INFO_CLIENT_MAX_CB_LEN, len_domain);
return 1;
}
- if (!s_check_rem(s, 2))
+ if (!s_check_rem_and_log(s, 2, "Parsing [MS-RDPBCGR] TS_INFO_PACKET cbUserName"))
{
return 1;
}
@@ -747,18 +904,21 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
* always sends autologon credentials, even when user has not
* configured any
*/
- if (len_user == 0)
+ if (len_user == 0 && self->rdp_layer->client_info.rdp_autologin)
{
+ LOG(LOG_LEVEL_DEBUG, "Client supplied user name is empty, disabling autologin");
self->rdp_layer->client_info.rdp_autologin = 0;
}
if (len_user >= INFO_CLIENT_MAX_CB_LEN)
{
- LOG(LOG_LEVEL_ERROR, "ERROR [xrdp_sec_process_logon_info()]: len_user >= %d", INFO_CLIENT_MAX_CB_LEN);
+ LOG(LOG_LEVEL_ERROR,
+ "Client supplied user name is too long. Max length %d, user name length %d",
+ INFO_CLIENT_MAX_CB_LEN, len_user);
return 1;
}
- if (!s_check_rem(s, 2))
+ if (!s_check_rem_and_log(s, 2, "Parsing [MS-RDPBCGR] TS_INFO_PACKET cbPassword"))
{
return 1;
}
@@ -766,11 +926,13 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
if (len_password >= INFO_CLIENT_MAX_CB_LEN)
{
- LOG(LOG_LEVEL_ERROR, "ERROR [xrdp_sec_process_logon_info()]: len_password >= %d", INFO_CLIENT_MAX_CB_LEN);
+ LOG(LOG_LEVEL_ERROR,
+ "Client supplied password is too long. Max length %d, password length %d",
+ INFO_CLIENT_MAX_CB_LEN, len_password);
return 1;
}
- if (!s_check_rem(s, 2))
+ if (!s_check_rem_and_log(s, 2, "Parsing [MS-RDPBCGR] TS_INFO_PACKET cbAlternateShell"))
{
return 1;
}
@@ -778,11 +940,13 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
if (len_program >= INFO_CLIENT_MAX_CB_LEN)
{
- LOG(LOG_LEVEL_ERROR, "ERROR [xrdp_sec_process_logon_info()]: len_program >= %d", INFO_CLIENT_MAX_CB_LEN);
+ LOG(LOG_LEVEL_ERROR,
+ "Client supplied program name is too long. Max length %d, program name length %d",
+ INFO_CLIENT_MAX_CB_LEN, len_program);
return 1;
}
- if (!s_check_rem(s, 2))
+ if (!s_check_rem_and_log(s, 2, "Parsing [MS-RDPBCGR] TS_INFO_PACKET cbWorkingDir"))
{
return 1;
}
@@ -790,35 +954,38 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
if (len_directory >= INFO_CLIENT_MAX_CB_LEN)
{
- LOG(LOG_LEVEL_ERROR, "ERROR [xrdp_sec_process_logon_info()]: len_directory >= %d", INFO_CLIENT_MAX_CB_LEN);
+ LOG(LOG_LEVEL_ERROR,
+ "Client supplied directory name is too long. Max length %d, directory name length %d",
+ INFO_CLIENT_MAX_CB_LEN, len_directory);
return 1;
}
if (unicode_utf16_in(s, len_domain, self->rdp_layer->client_info.domain, sizeof(self->rdp_layer->client_info.domain) - 1) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "ERROR reading domain");
return 1;
}
- LOG_DEVEL(LOG_LEVEL_TRACE, "domain %s", self->rdp_layer->client_info.domain);
+
if (unicode_utf16_in(s, len_user, self->rdp_layer->client_info.username, sizeof(self->rdp_layer->client_info.username) - 1) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "ERROR reading user name");
return 1;
}
-
if (flags & RDP_LOGON_AUTO)
{
if (unicode_utf16_in(s, len_password, self->rdp_layer->client_info.password, sizeof(self->rdp_layer->client_info.password) - 1) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "ERROR reading password");
return 1;
}
- LOG_DEVEL(LOG_LEVEL_TRACE, "flag RDP_LOGON_AUTO found");
}
else if (self->rdp_layer->client_info.enable_token_login
&& len_user > 0
&& len_password == 0
&& (sep = g_strchr(self->rdp_layer->client_info.username, '\x1f')) != NULL)
{
- LOG_DEVEL(LOG_LEVEL_TRACE, "Logon token detected");
+ LOG(LOG_LEVEL_DEBUG, "Client supplied a Logon token. Overwritting password with logon token.");
g_strncpy(self->rdp_layer->client_info.password, sep + 1,
sizeof(self->rdp_layer->client_info.password) - 1);
self->rdp_layer->client_info.username[sep - self->rdp_layer->client_info.username] = '\0';
@@ -826,71 +993,118 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
}
else
{
- if (!s_check_rem(s, len_password + 2))
+ if (!s_check_rem_and_log(s, len_password + 2, "Parsing [MS-RDPBCGR] TS_INFO_PACKET Password"))
{
return 1;
}
in_uint8s(s, len_password + 2);
if (self->rdp_layer->client_info.require_credentials)
{
- LOG(LOG_LEVEL_ERROR, "xrdp_sec_process_logon_info: credentials on cmd line is mandatory");
+ LOG(LOG_LEVEL_ERROR, "Server is configured to require that the "
+ "client enable auto logon with credentials, but the client did "
+ "not request auto logon.");
return 1; /* credentials on cmd line is mandatory */
}
}
if (self->rdp_layer->client_info.domain_user_separator[0] != '\0'
&& self->rdp_layer->client_info.domain[0] != '\0')
{
+ LOG(LOG_LEVEL_DEBUG, "Client supplied domain with user name. Overwritting user name with user name parsed from domain.");
int size = sizeof(self->rdp_layer->client_info.username);
g_strncat(self->rdp_layer->client_info.username, self->rdp_layer->client_info.domain_user_separator, size - 1 - g_strlen(self->rdp_layer->client_info.domain_user_separator));
g_strncat(self->rdp_layer->client_info.username, self->rdp_layer->client_info.domain, size - 1 - g_strlen(self->rdp_layer->client_info.domain));
}
- LOG_DEVEL(LOG_LEVEL_TRACE, "username %s", self->rdp_layer->client_info.username);
if (unicode_utf16_in(s, len_program, self->rdp_layer->client_info.program, sizeof(self->rdp_layer->client_info.program) - 1) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "ERROR reading program");
return 1;
}
- LOG_DEVEL(LOG_LEVEL_TRACE, "program %s", self->rdp_layer->client_info.program);
+
if (unicode_utf16_in(s, len_directory, self->rdp_layer->client_info.directory, sizeof(self->rdp_layer->client_info.directory) - 1) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "ERROR reading directory");
return 1;
}
- LOG_DEVEL(LOG_LEVEL_TRACE, "directory %s", self->rdp_layer->client_info.directory);
- if (flags & RDP_LOGON_BLOB)
- {
- if (!s_check_rem(s, 4))
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_INFO_PACKET "
+ "CodePage (ignored), flags 0x%8.8x, cbDomain %d, cbUserName %d, "
+ "cbPassword %d, cbAlternateShell %d, cbWorkingDir %d, Domain %s, "
+ "UserName %s, Password (omitted from log), AlternateShell %s, "
+ "WorkingDir %s", flags, len_domain,
+ len_user, len_password, len_program, len_directory,
+ self->rdp_layer->client_info.domain,
+ self->rdp_layer->client_info.username,
+ self->rdp_layer->client_info.program,
+ self->rdp_layer->client_info.directory);
+ LOG(LOG_LEVEL_DEBUG, "Client supplied domain: %s", self->rdp_layer->client_info.domain);
+ LOG(LOG_LEVEL_DEBUG, "Client supplied username: %s", self->rdp_layer->client_info.username);
+ LOG(LOG_LEVEL_DEBUG, "Client supplied password: <omitted from log>");
+ LOG(LOG_LEVEL_DEBUG, "Client supplied program: %s", self->rdp_layer->client_info.program);
+ LOG(LOG_LEVEL_DEBUG, "Client supplied directory: %s", self->rdp_layer->client_info.directory);
+
+ /* TODO: explain why the windows key flag is used to determine if the
+ TS_EXTENDED_INFO_PACKET should be parsed */
+ if (flags & RDP_LOGON_BLOB) /* INFO_ENABLEWINDOWSKEY */
+ {
+ if (!s_check_rem_and_log(s, 4, "Parsing [MS-RDPBCGR] TS_EXTENDED_INFO_PACKET "
+ "clientAddressFamily and cbClientAddress"))
{
return 1;
}
- in_uint8s(s, 2); /* unknown */
+ /* TS_EXTENDED_INFO_PACKET requiered 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)
{
+ LOG(LOG_LEVEL_ERROR, "ERROR reading ip");
return 1;
}
- if (!s_check_rem(s, 2))
+ 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)
{
+ LOG(LOG_LEVEL_ERROR, "ERROR reading clientDir");
return 1;
}
- if (!s_check_rem(s, 4 + 62 + 22 + 62 + 26 + 4))
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_EXTENDED_INFO_PACKET "
+ "<Requiered Fields> clientAddressFamily (ignored), "
+ "cbClientAddress (ignored), clientAddress (ignored), "
+ "cbClientDir (ignored), clientDir (ignored)");
+
+ /* TODO: MS-BCGR 2.2.1.11.1.1.1 says that all fields after the
+ client directory are optional. */
+ if (!s_check_rem_and_log(s, 4 + 64 + 20 + 64 + 20 + 4 + 4,
+ "Parsing [MS-RDPBCGR] TS_EXTENDED_INFO_PACKET "
+ "clientTimeZone, clientSessionId, and performanceFlags"))
{
return 1;
}
- in_uint8s(s, 4); /* len of timezone */
- in_uint8s(s, 62); /* skip */
- in_uint8s(s, 22); /* skip misc. */
- in_uint8s(s, 62); /* skip */
- in_uint8s(s, 26); /* skip stuff */
+ /* TS_TIME_ZONE_INFORMATION */
+ in_uint8s(s, 4); /* Bias (4) */
+ in_uint8s(s, 64); /* StandardName (64) */
+ in_uint8s(s, 20); /* StandardDate (16), StandardBias (4) */
+ in_uint8s(s, 64); /* DaylightName (64) */
+ in_uint8s(s, 20); /* DaylightDate (16), DaylightBias (4) */
+ in_uint8s(s, 4); /* TS_EXTENDED_INFO_PACKET clientSessionId (4) */
+
+ /* TS_EXTENDED_INFO_PACKET optional fields */
in_uint32_le(s, self->rdp_layer->client_info.rdp5_performanceflags);
+
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_EXTENDED_INFO_PACKET "
+ "<Optional Fields> clientTimeZone (ignored), "
+ "clientSessionId (ignored), performanceFlags 0x%8.8x, "
+ "cbAutoReconnectCookie (ignored), autoReconnectCookie (ignored), "
+ "reserved1 (ignored), reserved2 (ignored), "
+ "cbDynamicDSTTimeZoneKeyName (ignored), "
+ "dynamicDSTTimeZoneKeyName (ignored), "
+ "dynamicDaylightTimeDisabled (ignored)",
+ self->rdp_layer->client_info.rdp5_performanceflags);
}
- LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_sec_process_logon_info");
return 0;
}
@@ -901,21 +1115,24 @@ xrdp_sec_send_lic_initial(struct xrdp_sec *self)
{
struct stream *s;
- LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_send_lic_initial:");
+
make_stream(s);
init_stream(s, 8192);
if (xrdp_mcs_init(self->mcs_layer, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "xrdp_sec_send_lic_initial: xrdp_mcs_init failed");
free_stream(s);
return 1;
}
- out_uint8a(s, g_lic1, 322);
+ out_uint8a(s, g_lic1, sizeof(g_lic1));
s_mark_end(s);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPELE] SERVER_LICENSE_REQUEST");
if (xrdp_mcs_send(self->mcs_layer, s, MCS_GLOBAL_CHANNEL) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "Sending [MS-RDPELE] SERVER_LICENSE_REQUEST failed");
free_stream(s);
return 1;
}
@@ -925,6 +1142,10 @@ xrdp_sec_send_lic_initial(struct xrdp_sec *self)
}
/*****************************************************************************/
+/*
+ * Send a [MS-RDPELE] LICENSE_ERROR_MESSAGE with STATUS_VALID_CLIENT
+ * See also: [MS-RDPELE] 1.3.3 Licensing PDU Flows
+ */
/* returns error */
static int
xrdp_sec_send_lic_response(struct xrdp_sec *self)
@@ -936,15 +1157,18 @@ xrdp_sec_send_lic_response(struct xrdp_sec *self)
if (xrdp_mcs_init(self->mcs_layer, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "xrdp_sec_send_lic_response: xrdp_mcs_init failed");
free_stream(s);
return 1;
}
- out_uint8a(s, g_lic2, 20);
+ out_uint8a(s, g_lic2, sizeof(g_lic2));
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");
free_stream(s);
return 1;
}
@@ -965,6 +1189,7 @@ xrdp_sec_send_media_lic_response(struct xrdp_sec *self)
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;
}
@@ -972,8 +1197,10 @@ xrdp_sec_send_media_lic_response(struct xrdp_sec *self)
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");
free_stream(s);
return 1;
}
@@ -1180,14 +1407,14 @@ xrdp_sec_recv_fastpath(struct xrdp_sec *self, struct stream *s)
int pad;
#ifndef XRDP_DEBUG
- /* TODO: remove UNUSED_VAR once the `var` variable is used for more than
+ /* TODO: remove UNUSED_VAR once the `ver` variable is used for more than
logging in debug mode */
UNUSED_VAR(ver);
#endif
- LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_recv_fastpath:");
if (xrdp_fastpath_recv(self->fastpath_layer, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "xrdp_sec_recv_fastpath: xrdp_fastpath_recv failed");
return 1;
}
@@ -1195,47 +1422,65 @@ xrdp_sec_recv_fastpath(struct xrdp_sec *self, struct stream *s)
{
if (self->crypt_level == CRYPT_LEVEL_FIPS)
{
- if (!s_check_rem(s, 12))
+ if (!s_check_rem_and_log(s, 12, "Parsing [MS-RDPBCGR] TS_FP_FIPS_INFO"))
{
return 1;
}
+ /* TS_FP_FIPS_INFO */
in_uint16_le(s, len);
in_uint8(s, ver); /* length (2 bytes) */
+ in_uint8(s, pad);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received header [MS-RDPBCGR] TS_FP_FIPS_INFO "
+ "length %d, version %d, padlen %d", len, ver, pad);
if (len != 0x10) /* length MUST set to 0x10 */
{
+ LOG(LOG_LEVEL_ERROR, "Received header [MS-RDPBCGR] TS_FP_FIPS_INFO "
+ "invalid fastpath length. Expected 16, received %d", len);
return 1;
}
- in_uint8(s, pad);
- LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_recv_fastpath: len %d ver %d pad %d", len, ver, pad);
+
+ /* remainder of TS_FP_INPUT_PDU */
in_uint8s(s, 8); /* dataSignature (8 bytes), skip for now */
- LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_recv_fastpath: data len %d", (int)(s->end - s->p));
+ LOG_DEVEL(LOG_LEVEL_TRACE, "CRYPT_LEVEL_FIPS - data len %d",
+ (int)(s->end - s->p));
xrdp_sec_fips_decrypt(self, s->p, (int)(s->end - s->p));
s->end -= pad;
}
else
{
- if (!s_check_rem(s, 8))
+ if (!s_check_rem_and_log(s, 8,
+ "Parsing [MS-RDPBCGR] TS_FP_INPUT_PDU dataSignature"))
{
return 1;
}
+ /* remainder of TS_FP_INPUT_PDU */
in_uint8s(s, 8); /* dataSignature (8 bytes), skip for now */
xrdp_sec_decrypt(self, s->p, (int)(s->end - s->p));
}
}
- if (self->fastpath_layer->numEvents == 0)
+ if (self->fastpath_layer->numEvents == 0) /* set by xrdp_fastpath_recv() */
{
/**
* If numberEvents is not provided in fpInputHeader, it will be provided
* as one additional byte here.
*/
- if (!s_check_rem(s, 8))
+ if (!s_check_rem_and_log(s, 8, "Parsing [MS-RDPBCGR] TS_FP_INPUT_PDU numEvents"))
{
return 1;
}
in_uint8(s, self->fastpath_layer->numEvents); /* numEvents (1 byte) (optional) */
}
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_FP_INPUT_PDU "
+ "fpInputHeader.action (ignored), "
+ "fpInputHeader.numEvents (see final numEvents), "
+ "fpInputHeader.flags %d, length1 (ToDo), length2 (ToDo), "
+ "fipsInformation %s, dataSignature (ignored), numEvents %d",
+ self->fastpath_layer->secFlags,
+ (self->fastpath_layer->secFlags & FASTPATH_INPUT_ENCRYPTED) ? "(see above)" : "(not present)",
+ self->fastpath_layer->numEvents);
+
return 0;
}
/*****************************************************************************/
@@ -1248,63 +1493,85 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan)
int ver;
int pad;
- LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_sec_recv");
if (xrdp_mcs_recv(self->mcs_layer, s, chan) != 0)
{
- LOG(LOG_LEVEL_ERROR, " out xrdp_sec_recv : error");
+ LOG(LOG_LEVEL_ERROR, "xrdp_sec_recv: xrdp_mcs_recv failed");
return 1;
}
- if (!s_check_rem(s, 4))
+ /* TODO: check if moving this check until after the is_security_header_present
+ causes any issues.
+ the security header is optional (eg. TLS connections), so this
+ check should really be after the check if the security header is present,
+ this currently seems to be working by coincidence at the moment. */
+ if (!s_check_rem_and_log(s, 4, "Parsing [MS-RDPBCGR] TS_SECURITY_HEADER"))
{
return 1;
}
-
if (!(self->is_security_header_present))
{
+ /* noisy log statement with no real info since this is an
+ expected state for TLS connections
+ */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_sec_recv: security header NOT present");
return 0;
}
+ /* TS_SECURITY_HEADER */
in_uint32_le(s, flags);
- LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_sec_recv flags $%x", flags);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received header [MS-RDPBCGR] TS_SECURITY_HEADER "
+ "flags 0x%8.8x, flagsHi (merged with flags)", flags);
if (flags & SEC_ENCRYPT) /* 0x08 */
{
if (self->crypt_level == CRYPT_LEVEL_FIPS)
{
- if (!s_check_rem(s, 12))
+ if (!s_check_rem_and_log(s, 12, "Parsing [MS-RDPBCGR] TS_SECURITY_HEADER2"))
{
return 1;
}
- in_uint16_le(s, len);
- in_uint8(s, ver);
- if ((len != 16) || (ver != 1))
+ /* TS_SECURITY_HEADER2 */
+ in_uint16_le(s, len); /* length */
+ in_uint8(s, ver); /* version */
+ in_uint8(s, pad); /* padlen */
+ in_uint8s(s, 8); /* signature(8) */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received header [MS-RDPBCGR] TS_SECURITY_HEADER2 "
+ "length %d, version %d, padlen %d, dataSignature (ignored)",
+ len, ver, pad);
+ if (len != 16)
{
+ LOG(LOG_LEVEL_ERROR, "Received header [MS-RDPBCGR] TS_SECURITY_HEADER2 "
+ "has unexpected length. Expected 16, actual %d", len);
+ return 1;
+ }
+ if (ver != 1)
+ {
+ LOG(LOG_LEVEL_ERROR, "Received header [MS-RDPBCGR] TS_SECURITY_HEADER2 "
+ "has unexpected version. Expected 1, actual %d", ver);
return 1;
}
- in_uint8(s, pad);
- LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_recv: len %d ver %d pad %d", len, ver, pad);
- in_uint8s(s, 8); /* signature(8) */
- LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_recv: data len %d", (int)(s->end - s->p));
xrdp_sec_fips_decrypt(self, s->p, (int)(s->end - s->p));
s->end -= pad;
}
else if (self->crypt_level > CRYPT_LEVEL_NONE)
{
- if (!s_check_rem(s, 8))
+ if (!s_check_rem_and_log(s, 8, "Parsing [MS-RDPBCGR] TS_SECURITY_HEADER1"))
{
return 1;
}
+ /* TS_SECURITY_HEADER1 */
in_uint8s(s, 8); /* signature(8) */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received header [MS-RDPBCGR] TS_SECURITY_HEADER1 "
+ "dataSignature (ignored)");
xrdp_sec_decrypt(self, s->p, (int)(s->end - s->p));
}
}
- if (flags & SEC_CLIENT_RANDOM) /* 0x01 */
+ if (flags & SEC_CLIENT_RANDOM) /* 0x01 TS_SECURITY_PACKET */
{
- if (!s_check_rem(s, 4))
+ if (!s_check_rem_and_log(s, 4, "Parsing [MS-RDPBCGR] TS_SECURITY_PACKET"))
{
return 1;
}
@@ -1312,18 +1579,22 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan)
/* 512, 2048 bit */
if ((len != 64 + 8) && (len != 256 + 8))
{
+ LOG(LOG_LEVEL_ERROR, "xrdp_sec_recv : error - unexpected length %d", len);
return 1;
}
- if (!s_check_rem(s, len - 8))
+ if (!s_check_rem_and_log(s, len - 8,
+ "Parsing [MS-RDPBCGR] TS_SECURITY_PACKET encryptedClientRandom"))
{
return 1;
}
in_uint8a(s, self->client_crypt_random, len - 8);
+
xrdp_sec_rsa_op(self, self->client_random, self->client_crypt_random,
len - 8, self->pub_mod, self->pri_exp);
- LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_recv: client random - len %d", len);
- LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "client random", self->client_random, 256);
- LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "client crypt random", self->client_crypt_random, len - 8);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_SECURITY_PACKET "
+ "length %d, encryptedClientRandom (see below)", len);
+ LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "encryptedClientRandom", self->client_crypt_random, len - 8);
+ LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "decrypted encryptedClientRandom", self->client_random, 256);
if (self->crypt_level == CRYPT_LEVEL_FIPS)
{
xrdp_sec_fips_establish_keys(self);
@@ -1333,15 +1604,15 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan)
xrdp_sec_establish_keys(self);
}
*chan = 1; /* just set a non existing channel and exit */
- LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_recv");
+ LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_recv: out channel 1 (non-existing channel)");
return 0;
}
- if (flags & SEC_LOGON_INFO) /* 0x40 */
+ if (flags & SEC_LOGON_INFO) /* 0x40 SEC_INFO_PKT */
{
if (xrdp_sec_process_logon_info(self, s) != 0)
{
- LOG(LOG_LEVEL_ERROR, " out xrdp_sec_recv error");
+ LOG(LOG_LEVEL_ERROR, "xrdp_sec_recv: xrdp_sec_process_logon_info failed");
return 1;
}
@@ -1349,30 +1620,30 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan)
{
if (xrdp_sec_send_media_lic_response(self) != 0)
{
- LOG(LOG_LEVEL_ERROR, " out xrdp_sec_recv error");
+ LOG(LOG_LEVEL_ERROR, "xrdp_sec_recv: xrdp_sec_send_media_lic_response failed");
return 1;
}
- LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_recv");
+ LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_recv: out 'send demand active'");
return -1; /* special error that means send demand active */
}
if (xrdp_sec_send_lic_initial(self) != 0)
{
- LOG(LOG_LEVEL_ERROR, " out xrdp_sec_recv error");
+ LOG(LOG_LEVEL_ERROR, "xrdp_sec_recv: xrdp_sec_send_lic_initial failed");
return 1;
}
*chan = 1; /* just set a non existing channel and exit */
- LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_recv");
+ LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_recv: out channel 1 (non-existing channel)");
return 0;
}
- if (flags & SEC_LICENCE_NEG) /* 0x80 */
+ if (flags & SEC_LICENCE_NEG) /* 0x80 SEC_LICENSE_PKT */
{
if (xrdp_sec_send_lic_response(self) != 0)
{
- LOG(LOG_LEVEL_ERROR, " out xrdp_sec_recv error");
+ LOG(LOG_LEVEL_ERROR, "xrdp_sec_recv: xrdp_sec_send_lic_response failed");
return 1;
}
@@ -1383,11 +1654,10 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan)
self->is_security_header_present = 0;
}
- LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_recv");
+ LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_recv: out 'send demand active'");
return -1; /* special error that means send demand active */
}
- LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_recv");
return 0;
}
@@ -1458,15 +1728,12 @@ xrdp_sec_send(struct xrdp_sec *self, struct stream *s, int chan)
int datalen;
int pad;
- LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_send:");
- LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_sec_send");
s_pop_layer(s, sec_hdr);
if (self->crypt_level > CRYPT_LEVEL_NONE)
{
if (self->crypt_level == CRYPT_LEVEL_FIPS)
{
- LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_send: fips");
out_uint32_le(s, SEC_ENCRYPT);
datalen = (int)((s->end - s->p) - 12);
out_uint16_le(s, 16); /* crypto header size */
@@ -1477,6 +1744,11 @@ xrdp_sec_send(struct xrdp_sec *self, struct stream *s, int chan)
out_uint8(s, pad); /* fips pad */
xrdp_sec_fips_sign(self, s->p, 8, s->p + 8, datalen);
xrdp_sec_fips_encrypt(self, s->p + 8, datalen + pad);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPBCGR] TS_SECURITY_HEADER2 "
+ "flags 0x%4.4x, flagsHi 0x%4.4x, length 16, version 1, "
+ "padlen %d, dataSignature 0x%8.8x 0x%8.8x",
+ SEC_ENCRYPT & 0xffff, (SEC_ENCRYPT & 0xffff0000) >> 16,
+ pad, *((uint32_t *) s->p), *((uint32_t *) (s->p + 4)));
}
else if (self->crypt_level > CRYPT_LEVEL_LOW)
{
@@ -1484,19 +1756,25 @@ xrdp_sec_send(struct xrdp_sec *self, struct stream *s, int chan)
datalen = (int)((s->end - s->p) - 8);
xrdp_sec_sign(self, s->p, 8, s->p + 8, datalen);
xrdp_sec_encrypt(self, s->p + 8, datalen);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPBCGR] TS_SECURITY_HEADER1 "
+ "flags 0x%4.4x, flagsHi 0x%4.4x, dataSignature 0x%8.8x 0x%8.8x",
+ SEC_ENCRYPT & 0xffff, (SEC_ENCRYPT & 0xffff0000) >> 16,
+ *((uint32_t *) s->p), *((uint32_t *) (s->p + 4)));
}
else
{
out_uint32_le(s, 0);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPBCGR] TS_SECURITY_HEADER "
+ "flags 0x0000, flagsHi 0x0000");
}
}
if (xrdp_mcs_send(self->mcs_layer, s, chan) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "xrdp_sec_send: xrdp_mcs_send failed");
return 1;
}
- LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_send");
return 0;
}
@@ -1523,6 +1801,8 @@ xrdp_sec_init_fastpath(struct xrdp_sec *self, struct stream *s)
{
if (xrdp_fastpath_init(self->fastpath_layer, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "xrdp_sec_init_fastpath: xrdp_fastpath_init failed");
return 1;
}
if (self->crypt_level == CRYPT_LEVEL_FIPS)
@@ -1555,7 +1835,6 @@ xrdp_sec_send_fastpath(struct xrdp_sec *self, struct stream *s)
int error;
char save[8];
- LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_send_fastpath:");
error = 0;
s_pop_layer(s, sec_hdr);
if (self->crypt_level == CRYPT_LEVEL_FIPS)
@@ -1578,6 +1857,13 @@ xrdp_sec_send_fastpath(struct xrdp_sec *self, struct stream *s)
g_memcpy(save, s->p + 8 + datalen, pad);
g_memset(s->p + 8 + datalen, 0, pad);
xrdp_sec_fips_encrypt(self, s->p + 8, datalen + pad);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_FP_UPDATE_PDU "
+ "fpOutputHeader.action 0, fpOutputHeader.reserved 0, "
+ "fpOutputHeader.flags 0x2, length1 0x%2.2x, length2 0x%2.2x, "
+ "fipsInformation.length 16, fipsInformation.version 1, "
+ "fipsInformation.padlen %d, dataSignature 0x%8.8x 0x%8.8x, ",
+ pdulen >> 4, pdulen & 0xff, pad,
+ *((uint32_t *) s->p), *((uint32_t *) (s->p + 4)));
error = xrdp_fastpath_send(self->fastpath_layer, s);
g_memcpy(s->p + 8 + datalen, save, pad);
}
@@ -1593,22 +1879,33 @@ xrdp_sec_send_fastpath(struct xrdp_sec *self, struct stream *s)
out_uint16_be(s, pdulen);
xrdp_sec_sign(self, s->p, 8, s->p + 8, datalen);
xrdp_sec_encrypt(self, s->p + 8, datalen);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_FP_UPDATE_PDU "
+ "fpOutputHeader.action 0, fpOutputHeader.reserved 0, "
+ "fpOutputHeader.flags 0x2, length1 0x%2.2x, length2 0x%2.2x, "
+ "dataSignature 0x%8.8x 0x%8.8x, ",
+ pdulen >> 4, pdulen & 0xff,
+ *((uint32_t *) s->p), *((uint32_t *) (s->p + 4)));
error = xrdp_fastpath_send(self->fastpath_layer, s);
}
else
{
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_send_fastpath: no crypt");
pdulen = (int)(s->end - s->p);
- LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_send_fastpath: pdulen %d", pdulen);
secFlags = 0x0;
fpOutputHeader = secFlags << 6;
out_uint8(s, fpOutputHeader);
pdulen |= 0x8000;
out_uint16_be(s, pdulen);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_FP_UPDATE_PDU "
+ "fpOutputHeader.action 0, fpOutputHeader.reserved 0, "
+ "fpOutputHeader.flags 0, length1 0x%2.2x, length2 0x%2.2x",
+ pdulen >> 4, pdulen & 0xff);
error = xrdp_fastpath_send(self->fastpath_layer, s);
}
if (error != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "xrdp_sec_send_fastpath: xrdp_fastpath_send failed");
return 1;
}
return 0;
@@ -1627,11 +1924,11 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec *self, struct stream *s)
int earlyCapabilityFlags;
char clientName[INFO_CLIENT_NAME_BYTES / 2] = { '\0' };
+ /* TS_UD_CS_CORE requiered fields */
in_uint8s(s, 4); /* version */
in_uint16_le(s, self->rdp_layer->client_info.width);
in_uint16_le(s, self->rdp_layer->client_info.height);
in_uint16_le(s, colorDepth);
- LOG_DEVEL(LOG_LEVEL_TRACE, "colorDepth 0x%4.4x (0xca00 4bpp 0xca01 8bpp)", colorDepth);
switch (colorDepth)
{
case RNS_UD_COLOR_4BPP:
@@ -1645,14 +1942,34 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec *self, struct stream *s)
in_uint8s(s, 4); /* keyboardLayout */
in_uint8s(s, 4); /* clientBuild */
unicode_utf16_in(s, INFO_CLIENT_NAME_BYTES - 2, clientName, sizeof(clientName) - 1); /* clientName */
- LOG(LOG_LEVEL_INFO, "connected client computer name: %s", clientName);
+ LOG(LOG_LEVEL_INFO, "Connected client computer name: %s", clientName);
in_uint8s(s, 4); /* keyboardType */
in_uint8s(s, 4); /* keyboardSubType */
in_uint8s(s, 4); /* keyboardFunctionKey */
in_uint8s(s, 64); /* imeFileName */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_CORE "
+ "<Requiered fields> version (ignored), desktopWidth %d, "
+ "desktopHeight %d, colorDepth %s, SASSequence (ingored), "
+ "keyboardLayout (ignored), clientBuild (ignored), "
+ "clientName %s, keyboardType (ignored), "
+ "keyboardSubType (ignored), keyboardFunctionKey (ignored), "
+ "imeFileName (ignroed)",
+ self->rdp_layer->client_info.width,
+ self->rdp_layer->client_info.height,
+ (colorDepth == 0xca00 ? "RNS_UD_COLOR_4BPP" :
+ colorDepth == 0xca01 ? "RNS_UD_COLOR_8BPP" : "unknown"),
+ clientName);
+
+ /* TS_UD_CS_CORE optional fields */
in_uint16_le(s, postBeta2ColorDepth);
- LOG_DEVEL(LOG_LEVEL_TRACE, "postBeta2ColorDepth 0x%4.4x (0xca00 4bpp 0xca01 8bpp "
- "0xca02 15bpp 0xca03 16bpp 0xca04 24bpp)", postBeta2ColorDepth);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_CORE "
+ "<Optional Field> postBeta2ColorDepth %s",
+ postBeta2ColorDepth == 0xca00 ? "RNS_UD_COLOR_4BPP" :
+ postBeta2ColorDepth == 0xca01 ? "RNS_UD_COLOR_8BPP" :
+ postBeta2ColorDepth == 0xca02 ? "RNS_UD_COLOR_16BPP_555" :
+ postBeta2ColorDepth == 0xca03 ? "RNS_UD_COLOR_16BPP_565" :
+ postBeta2ColorDepth == 0xca04 ? "RNS_UD_COLOR_24BPP" :
+ "unknown");
switch (postBeta2ColorDepth)
{
@@ -1677,20 +1994,30 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec *self, struct stream *s)
return 0;
}
in_uint8s(s, 2); /* clientProductId */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_CORE "
+ "<Optional Field> clientProductId (ignored)");
if (!s_check_rem(s, 4))
{
return 0;
}
in_uint8s(s, 4); /* serialNumber */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_CORE "
+ "<Optional Field> serialNumber (ignored)");
if (!s_check_rem(s, 2))
{
return 0;
}
in_uint16_le(s, highColorDepth);
- LOG_DEVEL(LOG_LEVEL_TRACE, "highColorDepth 0x%4.4x (0x0004 4bpp 0x0008 8bpp 0x000f 15bpp "
- "0x0010 16 bpp 0x0018 24bpp)", highColorDepth);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_CORE "
+ "<Optional Field> highColorDepth %s",
+ highColorDepth == 0x0004 ? "HIGH_COLOR_4BPP" :
+ highColorDepth == 0x0008 ? "HIGH_COLOR_8BPP" :
+ highColorDepth == 0x000F ? "HIGH_COLOR_15BPP" :
+ highColorDepth == 0x0010 ? "HIGH_COLOR_16BPP" :
+ highColorDepth == 0x0018 ? "HIGH_COLOR_24BPP" :
+ "unknown");
self->rdp_layer->client_info.bpp = highColorDepth;
if (!s_check_rem(s, 2))
@@ -1698,8 +2025,13 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec *self, struct stream *s)
return 0;
}
in_uint16_le(s, supportedColorDepths);
- LOG_DEVEL(LOG_LEVEL_TRACE, "supportedColorDepths 0x%4.4x (0x0001 24bpp 0x0002 16bpp "
- "0x0004 15bpp 0x0008 32bpp)", supportedColorDepths);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_CORE "
+ "<Optional Field> supportedColorDepths %s",
+ supportedColorDepths == 0x0001 ? "RNS_UD_24BPP_SUPPORT" :
+ supportedColorDepths == 0x0002 ? "RNS_UD_16BPP_SUPPORT" :
+ supportedColorDepths == 0x0004 ? "RNS_UD_15BPP_SUPPORT" :
+ supportedColorDepths == 0x0008 ? "RNS_UD_32BPP_SUPPORT" :
+ "unknown");
if (!s_check_rem(s, 2))
{
@@ -1707,7 +2039,8 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec *self, struct stream *s)
}
in_uint16_le(s, earlyCapabilityFlags);
self->rdp_layer->client_info.mcs_early_capability_flags = earlyCapabilityFlags;
- LOG_DEVEL(LOG_LEVEL_TRACE, "earlyCapabilityFlags 0x%4.4x (0x0002 want32)",
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_CORE "
+ "<Optional Field> earlyCapabilityFlags 0x%4.4x",
earlyCapabilityFlags);
if ((earlyCapabilityFlags & 0x0002) && (supportedColorDepths & 0x0008))
{
@@ -1719,13 +2052,16 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec *self, struct stream *s)
return 0;
}
in_uint8s(s, 64); /* clientDigProductId */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_CORE "
+ "<Optional Field> clientDigProductId (ignored)");
if (!s_check_rem(s, 1))
{
return 0;
}
in_uint8(s, self->rdp_layer->client_info.mcs_connection_type); /* connectionType */
- LOG_DEVEL(LOG_LEVEL_TRACE, "got client client connection type 0x%8.8x",
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_CORE "
+ "<Optional Field> connectionType 0x%2.2x",
self->rdp_layer->client_info.mcs_connection_type);
if (!s_check_rem(s, 1))
@@ -1733,67 +2069,89 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec *self, struct stream *s)
return 0;
}
in_uint8s(s, 1); /* pad1octet */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_CORE "
+ "<Optional Field> pad1octet (ignored)");
if (!s_check_rem(s, 4))
{
return 0;
}
in_uint8s(s, 4); /* serverSelectedProtocol */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_CORE "
+ "<Optional Field> serverSelectedProtocol (ignored)");
if (!s_check_rem(s, 4))
{
return 0;
}
in_uint8s(s, 4); /* desktopPhysicalWidth */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_CORE "
+ "<Optional Field> desktopPhysicalWidth (ignored)");
if (!s_check_rem(s, 4))
{
return 0;
}
in_uint8s(s, 4); /* desktopPhysicalHeight */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_CORE "
+ "<Optional Field> desktopPhysicalHeight (ignored)");
if (!s_check_rem(s, 2))
{
return 0;
}
in_uint8s(s, 2); /* reserved */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_CORE "
+ "<Optional Field> desktopOrientation (ignored)");
return 0;
}
/*****************************************************************************/
+/* Process a [MS-RDPBCGR] TS_UD_CS_SEC message */
static int
xrdp_sec_process_mcs_data_CS_SECURITY(struct xrdp_sec *self, struct stream *s)
{
int crypt_method;
int found;
- LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_sec_process_mcs_data_CS_SECURITY:");
in_uint32_le(s, crypt_method);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_SEC "
+ "encryptionMethods 0x%8.8x, extEncryptionMethods (ignored)",
+ crypt_method);
if (crypt_method & CRYPT_METHOD_40BIT)
{
- LOG(LOG_LEVEL_INFO, " client supports 40 bit encryption");
+ LOG(LOG_LEVEL_DEBUG, "Client supports 40 bit encryption");
}
if (crypt_method & CRYPT_METHOD_128BIT)
{
- LOG(LOG_LEVEL_INFO, " client supports 128 bit encryption");
+ LOG(LOG_LEVEL_DEBUG, "Client supports 128 bit encryption");
}
if (crypt_method & CRYPT_METHOD_56BIT)
{
- LOG(LOG_LEVEL_INFO, " client supports 56 bit encryption");
+ LOG(LOG_LEVEL_DEBUG, "Client supports 56 bit encryption");
}
if (crypt_method & CRYPT_METHOD_FIPS)
{
- LOG(LOG_LEVEL_INFO, " client supports fips encryption");
+ LOG(LOG_LEVEL_DEBUG, "Client supports fips encryption");
}
found = 0;
if ((found == 0) &&
+ (self->mcs_layer->iso_layer->selectedProtocol == PROTOCOL_SSL))
+ {
+ LOG(LOG_LEVEL_DEBUG,
+ "The connection is using TLS, skipping RDP crypto negotiation");
+ found = 1;
+ }
+ if ((found == 0) &&
(self->crypt_method & CRYPT_METHOD_FIPS) &&
(self->crypt_level == CRYPT_LEVEL_FIPS))
{
if (crypt_method & CRYPT_METHOD_FIPS)
{
- LOG(LOG_LEVEL_INFO, " client and server support fips, using fips");
+ LOG(LOG_LEVEL_DEBUG,
+ "Client and server both support fips encryption, "
+ "using RDP fips encryption.");
self->crypt_method = CRYPT_METHOD_FIPS;
self->crypt_level = CRYPT_LEVEL_FIPS;
found = 1;
@@ -1805,21 +2163,27 @@ xrdp_sec_process_mcs_data_CS_SECURITY(struct xrdp_sec *self, struct stream *s)
{
if (crypt_method & CRYPT_METHOD_128BIT)
{
- LOG(LOG_LEVEL_INFO, " client and server support high crypt, using "
- "high crypt");
+ LOG(LOG_LEVEL_DEBUG,
+ "Client and server both support high encryption, "
+ "using RDP 128-bit encryption.");
self->crypt_method = CRYPT_METHOD_128BIT;
self->crypt_level = CRYPT_LEVEL_HIGH;
found = 1;
}
}
+ /* TODO: figure out why both "COMPATIBLE" and "LOW" crypto level both use
+ 40-bit encryption, and why there is no cypto method for 56-bit
+ encryption even though there is code for checking for 56-bit
+ encryption */
if ((found == 0) &&
(self->crypt_method & CRYPT_METHOD_40BIT) &&
(self->crypt_level == CRYPT_LEVEL_CLIENT_COMPATIBLE))
{
if (crypt_method & CRYPT_METHOD_40BIT)
{
- LOG(LOG_LEVEL_INFO, " client and server support medium crypt, using "
- "medium crypt");
+ LOG(LOG_LEVEL_DEBUG,
+ "Client and server both support medium encryption, "
+ "using RDP 40-bit encryption.");
self->crypt_method = CRYPT_METHOD_40BIT;
self->crypt_level = CRYPT_LEVEL_CLIENT_COMPATIBLE;
found = 1;
@@ -1831,8 +2195,9 @@ xrdp_sec_process_mcs_data_CS_SECURITY(struct xrdp_sec *self, struct stream *s)
{
if (crypt_method & CRYPT_METHOD_40BIT)
{
- LOG(LOG_LEVEL_INFO, " client and server support low crypt, using "
- "low crypt");
+ LOG(LOG_LEVEL_DEBUG,
+ "Client and server both support low encryption, "
+ "using RDP 40-bit encryption.");
self->crypt_method = CRYPT_METHOD_40BIT;
self->crypt_level = CRYPT_LEVEL_LOW;
found = 1;
@@ -1843,23 +2208,30 @@ xrdp_sec_process_mcs_data_CS_SECURITY(struct xrdp_sec *self, struct stream *s)
{
if (crypt_method == CRYPT_METHOD_NONE)
{
- LOG(LOG_LEVEL_INFO, " client and server support none crypt, using "
- "none crypt");
+ LOG(LOG_LEVEL_DEBUG,
+ "Client and server both support no encryption, "
+ "RDP encryption is disabled.");
self->crypt_method = CRYPT_METHOD_NONE;
self->crypt_level = CRYPT_LEVEL_NONE;
found = 1;
}
}
- // if (found == 0)
- // {
- // LOG_DEVEL(LOG_LEVEL_TRACE, " can not find client / server agreed encryption method");
- // return 1;
- // }
+ if (found == 0)
+ {
+ /* TODO: figure out why failing to find a shared encryption level
+ does not return an error? */
+ /* TODO: does the connection fail now or is the default server
+ encryption used? */
+ LOG(LOG_LEVEL_WARNING,
+ "Client and server do not both support the same encryption.");
+ // return 1;
+ }
return 0;
}
/*****************************************************************************/
-/* this adds the mcs channels in the list of channels to be used when
+/* Process a [MS-RDPBCGR] TS_UD_CS_NET message.
+ This adds the mcs channels in the list of channels to be used when
creating the server mcs data */
static int
xrdp_sec_process_mcs_data_channels(struct xrdp_sec *self, struct stream *s)
@@ -1870,47 +2242,56 @@ xrdp_sec_process_mcs_data_channels(struct xrdp_sec *self, struct stream *s)
struct mcs_channel_item *channel_item;
client_info = &(self->rdp_layer->client_info);
- LOG_DEVEL(LOG_LEVEL_TRACE, "processing channels, channels_allowed is %d",
- client_info->channels_allowed);
/* this is an option set in xrdp.ini */
if (client_info->channels_allowed == 0) /* are channels on? */
{
- LOG(LOG_LEVEL_INFO, "all channels are disabled by "
- "configuration");
+ LOG(LOG_LEVEL_DEBUG, "All channels are disabled by configuration");
return 0;
}
- if (!s_check_rem(s, 4))
+ if (!s_check_rem_and_log(s, 4, "Parsing [MS-RDPBCGR] TS_UD_CS_NET"))
{
return 1;
}
in_uint32_le(s, num_channels);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_NET "
+ "channelCount %d", num_channels);
if (num_channels > 31)
{
+ LOG(LOG_LEVEL_ERROR, "[MS-RDPBCGR] Protocol error: too many channels requested. "
+ "max 31, received %d", num_channels);
return 1;
}
for (index = 0; index < num_channels; index++)
{
channel_item = g_new0(struct mcs_channel_item, 1);
- if (!s_check_rem(s, 12))
+ if (!s_check_rem_and_log(s, 12, "Parsing [MS-RDPBCGR] TS_UD_CS_NET.CHANNEL_DEF"))
{
g_free(channel_item);
return 1;
}
in_uint8a(s, channel_item->name, 8);
in_uint32_le(s, channel_item->flags);
- if (g_strlen(channel_item->name) > 0)
+
+ if (g_strlen(channel_item->name) > 0 && g_strlen(channel_item->name) < 8)
{
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] "
+ "TS_UD_CS_NET.CHANNEL_DEF %d, name %s, options 0x%8.8x",
+ index, channel_item->name, channel_item->flags);
channel_item->chanid = MCS_GLOBAL_CHANNEL + (index + 1);
- LOG(LOG_LEVEL_INFO, "adding channel item name %s chan_id "
- "%d flags 0x%8.8x", channel_item->name,
- channel_item->chanid, channel_item->flags);
list_add_item(self->mcs_layer->channel_list,
(intptr_t) channel_item);
- LOG_DEVEL(LOG_LEVEL_TRACE, "got channel flags %8.8x name %s", channel_item->flags,
- channel_item->name);
+ LOG(LOG_LEVEL_DEBUG,
+ "Adding channel: name %s, channel id %d, flags 0x%8.8x",
+ channel_item->name, channel_item->chanid, channel_item->flags);
}
else
{
+ LOG_DEVEL(LOG_LEVEL_WARNING, "Received [MS-RDPBCGR] "
+ "TS_UD_CS_NET.CHANNEL_DEF %d, skipped because of "
+ "malformed channel name.", index);
+ LOG_DEVEL_HEXDUMP(LOG_LEVEL_WARNING,
+ "[MS-RDPBCGR] TS_UD_CS_NET.CHANNEL_DEF name",
+ channel_item->name, 8);
g_free(channel_item);
}
}
@@ -1918,7 +2299,8 @@ xrdp_sec_process_mcs_data_channels(struct xrdp_sec *self, struct stream *s)
}
/*****************************************************************************/
-/* reads the client monitors data */
+/* Process a [MS-RDPBCGR] TS_UD_CS_MONITOR message.
+ reads the client monitors data */
static int
xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s)
{
@@ -1934,33 +2316,38 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s)
client_info = &(self->rdp_layer->client_info);
- LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_process_mcs_data_monitors: processing monitors data, allow_multimon is %d", client_info->multimon);
/* this is an option set in xrdp.ini */
if (client_info->multimon != 1) /* are multi-monitors allowed ? */
{
- LOG_DEVEL(LOG_LEVEL_INFO, "[INFO] xrdp_sec_process_mcs_data_monitors: multimon is not "
- "allowed, skipping");
+ LOG(LOG_LEVEL_INFO, "Multi-monitor is disabled by server config");
return 0;
}
+ if (!s_check_rem_and_log(s, 8, "Parsing [MS-RDPBCGR] TS_UD_CS_MONITOR"))
+ {
+ return 1;
+ }
in_uint32_le(s, flags); /* flags */
+ in_uint32_le(s, monitorCount);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_MONITOR "
+ "flags 0x%8.8x, monitorCount %d", flags, monitorCount);
+
//verify flags - must be 0x0
if (flags != 0)
{
- LOG(LOG_LEVEL_ERROR, "[ERROR] xrdp_sec_process_mcs_data_monitors: flags MUST be "
- "zero, detected: %d", flags);
+ LOG(LOG_LEVEL_ERROR,
+ "[MS-RDPBCGR] Protocol error: TS_UD_CS_MONITOR flags MUST be zero, "
+ "received: 0x%8.8x", flags);
return 1;
}
- in_uint32_le(s, monitorCount);
//verify monitorCount - max 16
if (monitorCount > 16)
{
- LOG(LOG_LEVEL_ERROR, "[ERROR] xrdp_sec_process_mcs_data_monitors: max allowed "
- "monitors is 16, detected: %d", monitorCount);
+ LOG(LOG_LEVEL_ERROR,
+ "[MS-RDPBCGR] Protocol error: TS_UD_CS_MONITOR monitorCount "
+ "MUST be less than 16, received: %d", monitorCount);
return 1;
}
- LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_process_mcs_data_monitors: monitorCount= %d", monitorCount);
-
client_info->monitorCount = monitorCount;
x1 = 0;
@@ -1971,11 +2358,26 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s)
/* Add client_monitor_data to client_info struct, will later pass to X11rdp */
for (index = 0; index < monitorCount; index++)
{
+ if (!s_check_rem_and_log(s, 20, "Parsing [MS-RDPBCGR] TS_UD_CS_MONITOR.TS_MONITOR_DEF"))
+ {
+ return 1;
+ }
in_uint32_le(s, client_info->minfo[index].left);
in_uint32_le(s, client_info->minfo[index].top);
in_uint32_le(s, client_info->minfo[index].right);
in_uint32_le(s, client_info->minfo[index].bottom);
in_uint32_le(s, client_info->minfo[index].is_primary);
+
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] "
+ "TS_UD_CS_MONITOR.TS_MONITOR_DEF %d "
+ "left %d, top %d, right %d, bottom %d, flags 0x%8.8x",
+ index,
+ client_info->minfo[index].left,
+ client_info->minfo[index].top,
+ client_info->minfo[index].right,
+ client_info->minfo[index].bottom,
+ client_info->minfo[index].is_primary);
+
if (index == 0)
{
x1 = client_info->minfo[index].left;
@@ -1996,13 +2398,15 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s)
got_primary = 1;
}
- LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_process_mcs_data_monitors: got a monitor [%d]: left= %d, top= %d, right= %d, bottom= %d, is_primary?= %d",
- index,
- client_info->minfo[index].left,
- client_info->minfo[index].top,
- client_info->minfo[index].right,
- client_info->minfo[index].bottom,
- client_info->minfo[index].is_primary);
+ LOG(LOG_LEVEL_DEBUG,
+ "Client monitor [%d]: left= %d, top= %d, right= %d, bottom= %d, "
+ "is_primary?= %d",
+ index,
+ client_info->minfo[index].left,
+ client_info->minfo[index].top,
+ client_info->minfo[index].right,
+ client_info->minfo[index].bottom,
+ client_info->minfo[index].is_primary);
}
if (!got_primary)
@@ -2029,7 +2433,12 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s)
if (client_info->width > 0x7FFE || client_info->width < 0xC8 ||
client_info->height > 0x7FFE || client_info->height < 0xC8)
{
- LOG(LOG_LEVEL_ERROR, "[ERROR] xrdp_sec_process_mcs_data_monitors: error, virtual desktop width / height is too large");
+ LOG(LOG_LEVEL_ERROR,
+ "Client supplied virtual desktop width or height is invalid. "
+ "Allowed width range: min %d, max %d. Width received: %d. "
+ "Allowed height range: min %d, max %d. Height received: %d",
+ 0xC8, 0x7FFE, client_info->width,
+ 0xC8, 0x7FFE, client_info->height);
return 1; /* error */
}
@@ -2047,7 +2456,8 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s)
}
/*****************************************************************************/
-/* process client mcs data, we need some things in here to create the server
+/* Process a Client MCS Connect Initial PDU with GCC Conference Create Request.
+ process client mcs data, we need some things in here to create the server
mcs data */
int
xrdp_sec_process_mcs_data(struct xrdp_sec *self)
@@ -2061,51 +2471,66 @@ xrdp_sec_process_mcs_data(struct xrdp_sec *self)
/* set p to beginning */
s->p = s->data;
/* skip header */
- if (!s_check_rem(s, 23))
+ if (!s_check_rem_and_log(s, 23, "Parsing [ITU T.124] ConferenceCreateRequest"))
{
return 1;
}
- in_uint8s(s, 23);
+ in_uint8s(s, 23); /* skip [ITU T.124] ConferenceCreateRequest fields until userData */
while (s_check_rem(s, 4))
{
hold_p = s->p;
in_uint16_le(s, tag);
in_uint16_le(s, size);
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received header [MS-RDPBCGR] TS_UD_HEADER "
+ "type 0x%4.4x, length %d", tag, size);
- if ((size < 4) || (!s_check_rem(s, size - 4)))
+ if (size < 4)
+ {
+ LOG(LOG_LEVEL_WARNING, "[MS-RDPBCGR] Protocol error: Invalid TS_UD_HEADER length value. "
+ "expected >= 4, actual %d", size);
+ break;
+ }
+ if (!s_check_rem_and_log(s, size - 4,
+ "Parsing [MS-RDPBCGR] GCC Conference Create Request client data field"))
{
- LOG(LOG_LEVEL_ERROR, "error in xrdp_sec_process_mcs_data tag %d size %d",
- tag, size);
break;
}
- LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_process_mcs_data: 0x%8.8x", tag);
switch (tag)
{
case SEC_TAG_CLI_INFO: /* CS_CORE 0xC001 */
if (xrdp_sec_process_mcs_data_CS_CORE(self, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "Processing [MS-RDPBCGR] TS_UD_CS_CORE failed");
return 1;
}
break;
case SEC_TAG_CLI_CRYPT: /* CS_SECURITY 0xC002 */
if (xrdp_sec_process_mcs_data_CS_SECURITY(self, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "Processing [MS-RDPBCGR] TS_UD_CS_SEC failed");
return 1;
}
break;
case SEC_TAG_CLI_CHANNELS: /* CS_NET 0xC003 */
if (xrdp_sec_process_mcs_data_channels(self, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "Processing [MS-RDPBCGR] TS_UD_CS_NET failed");
return 1;
}
break;
case SEC_TAG_CLI_4: /* CS_CLUSTER 0xC004 */
+ LOG_DEVEL(LOG_LEVEL_DEBUG, "Received [MS-RDPBCGR] TS_UD_CS_CLUSTER - no-op");
break;
case SEC_TAG_CLI_MONITOR: /* CS_MONITOR 0xC005 */
if (xrdp_sec_process_mcs_data_monitors(self, s) != 0)
{
+ LOG(LOG_LEVEL_ERROR,
+ "Processing [MS-RDPBCGR] TS_UD_CS_MONITOR failed");
return 1;
}
break;
@@ -2118,8 +2543,9 @@ xrdp_sec_process_mcs_data(struct xrdp_sec *self)
SC_MCS_MSGCHANNEL 0x0C04
SC_MULTITRANSPORT 0x0C08 */
default:
- LOG(LOG_LEVEL_ERROR, "error unknown xrdp_sec_process_mcs_data "
- "tag 0x%4.4x size %d", tag, size);
+ LOG(LOG_LEVEL_WARNING,
+ "Received [MS-RDPBCGR] TS_UD_HEADER type 0x%4.4x "
+ "is unknown (ignored)", tag);
break;
}
@@ -2131,9 +2557,11 @@ xrdp_sec_process_mcs_data(struct xrdp_sec *self)
if (self->rdp_layer->client_info.bpp >
self->rdp_layer->client_info.max_bpp)
{
- LOG(LOG_LEVEL_INFO, "xrdp_rdp_parse_client_mcs_data: client asked "
- "for %dbpp connection but configuration is limited "
- "to %dbpp", self->rdp_layer->client_info.bpp,
+ LOG(LOG_LEVEL_WARNING, "Client requested %d bpp color depth, "
+ "but the server configuration is limited to %d bpp. "
+ "Downgrading the color depth to %d bits-per-pixel.",
+ self->rdp_layer->client_info.bpp,
+ self->rdp_layer->client_info.max_bpp,
self->rdp_layer->client_info.max_bpp);
self->rdp_layer->client_info.bpp =
self->rdp_layer->client_info.max_bpp;
@@ -2146,7 +2574,16 @@ xrdp_sec_process_mcs_data(struct xrdp_sec *self)
}
/*****************************************************************************/
-/* process the mcs client data we received from the mcs layer */
+/* Process the mcs client data [ITU T.124] ConferenceCreateRequest userData field
+ as a [MS-RDPBCGR] TS_UD_CS_CORE struct */
+/* TODO: why does this method parse the strust from back to front (resetting
+ after each field) instead of from front to back like the rest of the parsing
+ code? */
+/* TODO: why does this method exist when the same struct is parsed in
+ xrdp_sec_process_mcs_data_CS_CORE and there does not seem to be any
+ dependencies preventing a call to that function. */
+/* TODO: this is a brittle function that assumes field offsets in the stream
+ instead of parsing the variable length fields of [ITU T.124] ConferenceCreateRequest */
static int
xrdp_sec_in_mcs_data(struct xrdp_sec *self)
{
@@ -2159,18 +2596,22 @@ xrdp_sec_in_mcs_data(struct xrdp_sec *self)
s = &(self->client_mcs_data);
/* get hostname, it's unicode */
s->p = s->data;
- if (!s_check_rem(s, 47))
+ if (!s_check_rem_and_log(s, 47, "Parsing [ITU T.124] ConferenceCreateRequest"))
{
return 1;
}
- in_uint8s(s, 47);
+ 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(s, 2))
+ if (!s_check_rem_and_log(s, 2, "Parsing [MS-RDPBCGR] TS_UD_CS_CORE clientName"))
{
return 1;
}
@@ -2181,31 +2622,45 @@ xrdp_sec_in_mcs_data(struct xrdp_sec *self)
}
/* get build */
s->p = s->data;
- if (!s_check_rem(s, 43 + 4))
+ if (!s_check_rem_and_log(s, 43 + 4, "Parsing [MS-RDPBCGR] TS_UD_CS_CORE clientBuild"))
{
return 1;
}
in_uint8s(s, 43);
- in_uint32_le(s, client_info->build);
+ in_uint32_le(s, client_info->build); /* [MS-RDPBCGR] TS_UD_CS_CORE clientBuild */
/* get keylayout */
s->p = s->data;
- if (!s_check_rem(s, 39 + 4))
+ if (!s_check_rem_and_log(s, 39 + 4, "Parsing [MS-RDPBCGR] TS_UD_CS_CORE keyboardLayout"))
{
return 1;
}
in_uint8s(s, 39);
- in_uint32_le(s, client_info->keylayout);
+ in_uint32_le(s, client_info->keylayout); /* [MS-RDPBCGR] TS_UD_CS_CORE keyboardLayout */
/* get keyboard type / subtype */
s->p = s->data;
- if (!s_check_rem(s, 79 + 8))
+ if (!s_check_rem_and_log(s, 79 + 8, "Parsing [MS-RDPBCGR] TS_UD_CS_CORE keyboardType"))
{
return 1;
}
in_uint8s(s, 79);
- in_uint32_le(s, client_info->keyboard_type);
- in_uint32_le(s, client_info->keyboard_subtype);
+ in_uint32_le(s, client_info->keyboard_type); /* [MS-RDPBCGR] TS_UD_CS_CORE keyboardType */
+ in_uint32_le(s, client_info->keyboard_subtype); /* [MS-RDPBCGR] TS_UD_CS_CORE keyboardSubType */
+ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_CORE "
+ "<Requiered fields> version (ignored), desktopWidth (ignored), "
+ "desktopHeight (ignored), colorDepth (ignored), SASSequence (ingored), "
+ "keyboardLayout 0x%8.8x, clientBuild %d, "
+ "clientName %s, keyboardType 0x%8.8x, "
+ "keyboardSubType 0x%8.8x, keyboardFunctionKey (ignored), "
+ "imeFileName (ignroed)",
+ client_info->keylayout,
+ client_info->build,
+ client_info->hostname,
+ client_info->keyboard_type,
+ client_info->keyboard_subtype);
+
xrdp_load_keyboard_layout(client_info);
s->p = s->data;
+
return 0;
}
@@ -2237,13 +2692,15 @@ xrdp_sec_init_rdp_security(struct xrdp_sec *self)
self->crypt_level = CRYPT_LEVEL_FIPS;
break;
default:
- LOG_DEVEL(LOG_LEVEL_TRACE, "Fatal : Illegal crypt_level");
+ LOG_DEVEL(LOG_LEVEL_WARNING, "Fatal : Illegal crypt_level %d",
+ self->rdp_layer->client_info.crypt_level);
break ;
}
if (self->decrypt_rc4_info != NULL)
{
- LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_sec_init_rdp_security: decrypt_rc4_info already created !!!");
+ LOG_DEVEL(LOG_LEVEL_WARNING,
+ "xrdp_sec_init_rdp_security: decrypt_rc4_info already created !!!");
}
else
{
@@ -2252,7 +2709,8 @@ xrdp_sec_init_rdp_security(struct xrdp_sec *self)
if (self->encrypt_rc4_info != NULL)
{
- LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_sec_init_rdp_security: encrypt_rc4_info already created !!!");
+ LOG_DEVEL(LOG_LEVEL_WARNING,
+ "xrdp_sec_init_rdp_security: encrypt_rc4_info already created !!!");
}
else
{
@@ -2274,7 +2732,6 @@ xrdp_sec_incoming(struct xrdp_sec *self)
char *value = NULL;
char key_file[256];
- LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_sec_incoming:");
iso = self->mcs_layer->iso_layer;
/* negotiate security layer */
@@ -2288,7 +2745,6 @@ xrdp_sec_incoming(struct xrdp_sec *self)
if (iso->selectedProtocol > PROTOCOL_RDP)
{
/* init tls security */
- LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_sec_incoming: init tls security");
if (trans_set_tls_mode(self->mcs_layer->iso_layer->trans,
self->rdp_layer->client_info.key_file,
@@ -2296,10 +2752,12 @@ xrdp_sec_incoming(struct xrdp_sec *self)
self->rdp_layer->client_info.ssl_protocols,
self->rdp_layer->client_info.tls_ciphers) != 0)
{
- LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_sec_incoming: trans_set_tls_mode failed");
+ LOG(LOG_LEVEL_ERROR, "xrdp_sec_incoming: trans_set_tls_mode failed");
return 1;
}
+ LOG(LOG_LEVEL_DEBUG, "Using TLS security, and "
+ "setting RDP security crypto to LEVEL_NONE and METHOD_NONE");
self->crypt_level = CRYPT_LEVEL_NONE;
self->crypt_method = CRYPT_METHOD_NONE;
self->rsa_key_bytes = 0;
@@ -2308,14 +2766,16 @@ xrdp_sec_incoming(struct xrdp_sec *self)
else
{
/* init rdp security */
- LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_sec_incoming: init rdp security");
if (xrdp_sec_init_rdp_security(self) != 0)
{
- LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_sec_incoming: xrdp_sec_init_rdp_security failed");
+ LOG(LOG_LEVEL_ERROR, "xrdp_sec_incoming: xrdp_sec_init_rdp_security failed");
return 1;
}
if (self->crypt_method != CRYPT_METHOD_NONE)
{
+ LOG(LOG_LEVEL_DEBUG, "Using RDP security, and "
+ "reading the server configuration");
+
g_memset(key_file, 0, sizeof(char) * 256);
g_random(self->server_random, 32);
items = list_create();
@@ -2327,7 +2787,7 @@ xrdp_sec_incoming(struct xrdp_sec *self)
if (file_by_name_read_section(key_file, "keys", items, values) != 0)
{
/* this is a show stopper */
- LOG(LOG_LEVEL_ALWAYS, "XRDP cannot read file: %s "
+ LOG(LOG_LEVEL_ERROR, "XRDP cannot read file: %s "
"(check permissions)", key_file);
list_delete(items);
list_delete(values);
@@ -2346,7 +2806,8 @@ xrdp_sec_incoming(struct xrdp_sec *self)
else if (g_strcasecmp(item, "pub_mod") == 0)
{
self->rsa_key_bytes = (g_strlen(value) + 1) / 5;
- LOG_DEVEL(LOG_LEVEL_TRACE, "pub_mod bytes %d", self->rsa_key_bytes);
+ LOG_DEVEL(LOG_LEVEL_DEBUG, "Server config: pub_mod bytes %d",
+ self->rsa_key_bytes);
hex_str_to_bin(value, self->pub_mod, self->rsa_key_bytes);
}
else if (g_strcasecmp(item, "pub_sig") == 0)
@@ -2356,15 +2817,14 @@ xrdp_sec_incoming(struct xrdp_sec *self)
else if (g_strcasecmp(item, "pri_exp") == 0)
{
self->rsa_key_bytes = (g_strlen(value) + 1) / 5;
- LOG_DEVEL(LOG_LEVEL_TRACE, "pri_exp %d", self->rsa_key_bytes);
+ LOG_DEVEL(LOG_LEVEL_DEBUG, "Server config: pri_exp %d",
+ self->rsa_key_bytes);
hex_str_to_bin(value, self->pri_exp, self->rsa_key_bytes);
}
}
if (self->rsa_key_bytes <= 64)
{
- LOG_DEVEL(LOG_LEVEL_TRACE, "warning, RSA key len 512 "
- "bits or less, consider creating a 2048 bit key");
LOG(LOG_LEVEL_WARNING, "warning, RSA key len 512 "
"bits or less, consider creating a 2048 bit key");
}
@@ -2377,20 +2837,23 @@ xrdp_sec_incoming(struct xrdp_sec *self)
/* negotiate mcs layer */
if (xrdp_mcs_incoming(self->mcs_layer) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "xrdp_sec_incoming: xrdp_mcs_incoming failed");
return 1;
}
- LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "client mcs data received", self->client_mcs_data.data,
+ LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "client mcs data received",
+ self->client_mcs_data.data,
(int)(self->client_mcs_data.end - self->client_mcs_data.data));
- LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "server mcs data sent", self->server_mcs_data.data,
+ LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "server mcs data sent",
+ self->server_mcs_data.data,
(int)(self->server_mcs_data.end - self->server_mcs_data.data));
- LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_incoming");
+
if (xrdp_sec_in_mcs_data(self) != 0)
{
+ LOG(LOG_LEVEL_ERROR, "xrdp_sec_incoming: xrdp_sec_in_mcs_data failed");
return 1;
}
- LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_incoming: out");
return 0;
}
@@ -2400,8 +2863,6 @@ xrdp_sec_disconnect(struct xrdp_sec *self)
{
int rv;
- LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_sec_disconnect");
rv = xrdp_mcs_disconnect(self->mcs_layer);
- LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_disconnect");
return rv;
}