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
This commit is contained in:
aquesnel 2021-02-04 05:11:54 -05:00 committed by GitHub
parent 42150c5c4f
commit 0ec471b02d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 2759 additions and 895 deletions

View File

@ -22,6 +22,7 @@
#include <pthread.h>
#include "arch.h"
#include "defines.h"
#include "list.h"
/* logging buffer size */
@ -95,7 +96,7 @@ enum logReturns
* @param ... the arguments for the printf format c-string
*/
#define LOG_DEVEL(log_level, args...) \
log_message_with_location(__func__, __FILE__, __LINE__, log_level, args);
log_message_with_location(__func__, __FILE__, __LINE__, log_level, args)
/**
* @brief Logging macro for messages that are for a systeam administrator to
@ -109,7 +110,7 @@ enum logReturns
* @param ... the arguments for the printf format c-string
*/
#define LOG(log_level, args...) \
log_message_with_location(__func__, __FILE__, __LINE__, log_level, args);
log_message_with_location(__func__, __FILE__, __LINE__, log_level, args)
/**
* @brief Logging macro for logging the contents of a byte array using a hex
@ -124,12 +125,16 @@ enum logReturns
* @param length, the length of the byte array to log
*/
#define LOG_DEVEL_HEXDUMP(log_level, message, buffer, length) \
log_hexdump_with_location(__func__, __FILE__, __LINE__, log_level, message, buffer, length);
log_hexdump_with_location(__func__, __FILE__, __LINE__, log_level, message, buffer, length)
#else
#define LOG_DEVEL(log_level, args...)
#define LOG(log_level, args...) log_message(log_level, args);
#define LOG_DEVEL_HEXDUMP(log_level, message, buffer, length)
#define LOG(log_level, args...) log_message(log_level, args)
/* Since log_message() returns a value ensure that the elided versions of
* LOG_DEVEL and LOG_DEVEL_HEXDUMP also "fake" returning the success value
*/
#define LOG_DEVEL(log_level, args...) UNUSED_VAR(LOG_STARTUP_OK)
#define LOG_DEVEL_HEXDUMP(log_level, message, buffer, length) UNUSED_VAR(LOG_STARTUP_OK)
#endif

View File

@ -369,6 +369,15 @@
#define PDUTYPE_DATAPDU 0x7
#define PDUTYPE_SERVER_REDIR_PKT 0xA
#define PDUTYPE_TO_STR(pdu_type) \
((pdu_type) == PDUTYPE_DEMANDACTIVEPDU ? "PDUTYPE_DEMANDACTIVEPDU" : \
(pdu_type) == PDUTYPE_CONFIRMACTIVEPDU ? "PDUTYPE_CONFIRMACTIVEPDU" : \
(pdu_type) == PDUTYPE_DEACTIVATEALLPDU ? "PDUTYPE_DEACTIVATEALLPDU" : \
(pdu_type) == PDUTYPE_DATAPDU ? "PDUTYPE_DATAPDU" : \
(pdu_type) == PDUTYPE_SERVER_REDIR_PKT ? "PDUTYPE_SERVER_REDIR_PKT" : \
"unknown" \
)
/* Share Data Header: pduType2 (2.2.8.1.1.1.2) */
/* TODO: to be renamed */
#define RDP_DATA_PDU_UPDATE 2 /* PDUTYPE2_UPDATE */
@ -378,6 +387,9 @@
#define RDP_DATA_PDU_SYNCHRONISE 31
#define PDUTYPE2_REFRESH_RECT 33
#define RDP_DATA_PDU_PLAY_SOUND 34
#define PDUTYPE2_SUPPRESS_OUTPUT 35
#define PDUTYPE2_SHUTDOWN_REQUEST 36
#define PDUTYPE2_SHUTDOWN_DENIED 37
#define RDP_DATA_PDU_LOGON 38
#define RDP_DATA_PDU_FONT2 39
#define RDP_DATA_PDU_DISCONNECT 47
@ -457,6 +469,14 @@
#define RDP_UPDATE_PALETTE 2
#define RDP_UPDATE_SYNCHRONIZE 3
#define GRAPHICS_UPDATE_TYPE_TO_STR(type) \
((type) == RDP_UPDATE_ORDERS ? "RDP_UPDATE_ORDERS" : \
(type) == RDP_UPDATE_BITMAP ? "RDP_UPDATE_BITMAP" : \
(type) == RDP_UPDATE_PALETTE ? "RDP_UPDATE_PALETTE" : \
(type) == RDP_UPDATE_SYNCHRONIZE ? "RDP_UPDATE_SYNCHRONIZE" : \
"unknown" \
)
/* Server Pointer Update PDU: messageType (2.2.9.1.1.4) */
/* TODO: to be renamed */
#define RDP_POINTER_SYSTEM 1 /* TS_PTRMSGTYPE_SYSTEM */

View File

@ -26,6 +26,7 @@
#define PARSE_H
#include "arch.h"
#include "log.h"
#if defined(L_ENDIAN)
#elif defined(B_ENDIAN)
@ -54,17 +55,63 @@ struct stream
};
/******************************************************************************/
#define s_check(s) ((s)->p <= (s)->end)
#define s_check(s) s_check_rem(s, 0)
/******************************************************************************/
#define s_check_rem(s, n) ((s)->p + (n) <= (s)->end)
/******************************************************************************/
/**
* @returns true if there are at least n bytes remaining in the stream,
* else false and logs an error message
*/
#define s_check_rem_and_log(s, n, msg_prefix) \
( s_check_rem((s), (n)) ? \
1 : \
LOG(LOG_LEVEL_ERROR, \
"%s Not enough bytes in the stream: expected %d, remaining %d", \
(msg_prefix), (n), s_rem(s)) \
&& 0 )
/******************************************************************************/
#define s_check_rem_out(s, n) ((s)->p + (n) <= (s)->data + (s)->size)
/******************************************************************************/
/**
* @returns true if there are at least n bytes remaining in the stream,
* else false and logs an error message
*/
#define s_check_rem_out_and_log(s, n, msg_prefix) \
( s_check_rem_out((s), (n)) ? \
1 : \
LOG(LOG_LEVEL_ERROR, \
"%s Not enough bytes in the stream: expected %d, remaining %d", \
(msg_prefix), (n), s_rem_out(s)) \
&& 0 )
/******************************************************************************/
#define s_check_end(s) ((s)->p == (s)->end)
/******************************************************************************/
/**
* @returns true if there are exactly 0 bytes remaining in the stream,
* else false and logs an error message
*/
#define s_check_end_and_log(s, msg_prefix) \
( s_check_end((s)) ? \
1 : \
LOG(LOG_LEVEL_ERROR, \
"%s Expected to be at the end of the stream, " \
"but there are %d bytes remaining", \
(msg_prefix), s_rem(s)) \
&& 0 )
/******************************************************************************/
#define s_rem(s) ((int) ((s)->end - (s)->p))
/******************************************************************************/
#define s_rem_out(s) ((int) ((s)->data + (s)->size - (s)->p))
/******************************************************************************/
#define make_stream(s) \
(s) = (struct stream*)g_malloc(sizeof(struct stream), 1)

View File

@ -95,8 +95,8 @@
* not yet sorted out
*/
#define MCS_CONNECT_INITIAL 0x7f65
#define MCS_CONNECT_RESPONSE 0x7f66
#define MCS_CONNECT_INITIAL 0x7f65 /* MCS BER: big endian, class=application (0x4000), constructed (0x2000), tag number > 30 (0x1f00), tag number=101 (0x0065) */
#define MCS_CONNECT_RESPONSE 0x7f66 /* MCS BER: application 102 */
#define BER_TAG_BOOLEAN 1
#define BER_TAG_INTEGER 2

View File

@ -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;
}
}
/* 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 */
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);
/* 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);
}

View File

@ -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);

View File

@ -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 &&

View File

@ -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 ((cap_version != 2) && (cap_version != 3))
if (!s_check_rem_and_log(s, 3, "Parsing [MS-RDPEDYC] DYNVC_CAPS_RSP"))
{
LOG(LOG_LEVEL_ERROR, "drdynvc_process_capability_response: incompatible DVC "
"version %d detected", cap_version);
return 1;
}
LOG(LOG_LEVEL_INFO, "drdynvc_process_capability_response: DVC version %d selected",
cap_version);
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,
"Dynamic Virtual Channel version %d is not supported",
cap_version);
return 1;
}
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_and_log(s, 4, "Parsing [MS-RDPEDYC] DYNVC_CREATE_RSP"))
{
return 1;
}
if (!s_check_rem(s, 4))
{
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;
}

View File

@ -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;
}
}

View File

@ -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;
}

File diff suppressed because it is too large Load Diff

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -789,7 +789,7 @@ xfuse_add_clip_dir_item(const char *filename, int flags, int size, int lindex)
if (g_xfs == NULL)
{
LOG_DEVEL(LOG_LEVEL_ERROR,
"xfuse_add_clip_dir_item() called with no filesystem")
"xfuse_add_clip_dir_item() called with no filesystem");
}
else
{