summaryrefslogtreecommitdiffstats
path: root/libxrdp
diff options
context:
space:
mode:
Diffstat (limited to 'libxrdp')
-rw-r--r--libxrdp/Makefile.am9
-rw-r--r--libxrdp/libxrdp.c166
-rw-r--r--libxrdp/xrdp_bitmap32_compress.c122
-rw-r--r--libxrdp/xrdp_bitmap_compress.c8
-rw-r--r--libxrdp/xrdp_caps.c114
-rw-r--r--libxrdp/xrdp_fastpath.c30
-rw-r--r--libxrdp/xrdp_iso.c9
-rw-r--r--libxrdp/xrdp_jpeg_compress.c53
-rw-r--r--libxrdp/xrdp_orders.c115
-rw-r--r--libxrdp/xrdp_rdp.c15
-rw-r--r--libxrdp/xrdp_sec.c12
11 files changed, 465 insertions, 188 deletions
diff --git a/libxrdp/Makefile.am b/libxrdp/Makefile.am
index b7d1dc26..3812de9c 100644
--- a/libxrdp/Makefile.am
+++ b/libxrdp/Makefile.am
@@ -1,3 +1,6 @@
+EXTRA_DIST = \
+ xrdp_surface.c
+
AM_CPPFLAGS = \
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
-DXRDP_SBIN_PATH=\"${sbindir}\" \
@@ -11,8 +14,6 @@ LIBXRDP_EXTRA_LIBS =
if XRDP_DEBUG
AM_CPPFLAGS += -DXRDP_DEBUG
-else
-AM_CPPFLAGS += -DXRDP_NODEBUG
endif
if XRDP_NEUTRINORDP
@@ -20,6 +21,10 @@ AM_CPPFLAGS += -DXRDP_NEUTRINORDP
LIBXRDP_EXTRA_LIBS += $(FREERDP_LIBS)
endif
+if XRDP_RFXCODEC
+AM_CPPFLAGS += -DXRDP_RFXCODEC
+endif
+
if XRDP_TJPEG
AM_CPPFLAGS += -DXRDP_JPEG -DXRDP_TJPEG @TurboJpegIncDir@
AM_LDFLAGS += @TurboJpegLibDir@
diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c
index c3763bf5..827b1247 100644
--- a/libxrdp/libxrdp.c
+++ b/libxrdp/libxrdp.c
@@ -27,6 +27,8 @@
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0)
+#define MAX_BITMAP_BUF_SIZE (16 * 1024) /* 16K */
+
/******************************************************************************/
struct xrdp_session *EXPORT_CC
libxrdp_init(tbus id, struct trans *trans)
@@ -373,15 +375,15 @@ libxrdp_send_bell(struct xrdp_session *session)
return 0;
}
-
/*****************************************************************************/
int EXPORT_CC
libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
int bpp, char *data, int x, int y, int cx, int cy)
{
- int line_size = 0;
+ int line_bytes = 0;
int i = 0;
int j = 0;
+ int k;
int total_lines = 0;
int lines_sending = 0;
int Bpp = 0;
@@ -389,27 +391,43 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
int bufsize = 0;
int total_bufsize = 0;
int num_updates = 0;
+ int line_pad_bytes;
+ int server_line_bytes;
char *p_num_updates = (char *)NULL;
char *p = (char *)NULL;
char *q = (char *)NULL;
struct stream *s = (struct stream *)NULL;
struct stream *temp_s = (struct stream *)NULL;
+ tui32 pixel;
- DEBUG(("libxrdp_send_bitmap sending bitmap"));
+ LLOGLN(10, ("libxrdp_send_bitmap: sending bitmap"));
Bpp = (bpp + 7) / 8;
- e = width % 4;
-
- if (e != 0)
+ e = (4 - width) & 3;
+ switch (bpp)
{
- e = 4 - e;
+ case 15:
+ case 16:
+ server_line_bytes = width * 2;
+ break;
+ case 24:
+ case 32:
+ server_line_bytes = width * 4;
+ break;
+ default: /* 8 bpp */
+ server_line_bytes = width;
+ break;
}
+ line_bytes = width * Bpp;
+ line_pad_bytes = line_bytes + e * Bpp;
- line_size = width * Bpp;
+ LLOGLN(10, ("libxrdp_send_bitmap: bpp %d Bpp %d line_bytes %d "
+ "server_line_bytes %d", bpp, Bpp, line_bytes, server_line_bytes));
make_stream(s);
- init_stream(s, 8192);
+ init_stream(s, MAX_BITMAP_BUF_SIZE);
if (session->client_info->use_bitmap_comp)
{
+ LLOGLN(10, ("libxrdp_send_bitmap: compression"));
make_stream(temp_s);
init_stream(temp_s, 65536);
i = 0;
@@ -421,6 +439,8 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
while (i > 0)
{
+ LLOGLN(10, ("libxrdp_send_bitmap: i %d", i));
+
total_bufsize = 0;
num_updates = 0;
xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s);
@@ -440,10 +460,26 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
}
p = s->p;
- lines_sending = xrdp_bitmap_compress(data, width, height,
- s, bpp,
- 4096 - total_bufsize,
- i - 1, temp_s, e);
+
+ if (bpp > 24)
+ {
+ LLOGLN(10, ("libxrdp_send_bitmap: 32 bpp"));
+ lines_sending = xrdp_bitmap32_compress(data, width, height,
+ s, 32,
+ (MAX_BITMAP_BUF_SIZE - 100) - total_bufsize,
+ i - 1, temp_s, e, 0x10);
+ LLOGLN(10, ("libxrdp_send_bitmap: i %d lines_sending %d",
+ i, lines_sending));
+ }
+ else
+ {
+ lines_sending = xrdp_bitmap_compress(data, width, height,
+ s, bpp,
+ (MAX_BITMAP_BUF_SIZE - 100) - total_bufsize,
+ i - 1, temp_s, e);
+ LLOGLN(10, ("libxrdp_send_bitmap: i %d lines_sending %d",
+ i, lines_sending));
+ }
if (lines_sending == 0)
{
@@ -470,6 +506,7 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
out_uint16_le(s, bufsize); /* compressed size */
j = (width + e) * Bpp;
j = j * lines_sending;
+ total_bufsize += 18; /* bytes since pop layer */
}
else
{
@@ -481,31 +518,42 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
out_uint16_le(s, j); /* line size */
j = j * lines_sending;
out_uint16_le(s, j); /* final size */
+ total_bufsize += 26; /* bytes since pop layer */
}
- if (j > 32768)
+ LLOGLN(10, ("libxrdp_send_bitmap: decompressed pixels %d "
+ "decompressed bytes %d compressed bytes %d",
+ lines_sending * (width + e),
+ line_pad_bytes * lines_sending, bufsize));
+
+ if (j > MAX_BITMAP_BUF_SIZE)
{
- g_writeln("error, decompressed size too big: %d bytes", j);
+ LLOGLN(0, ("libxrdp_send_bitmap: error, decompressed "
+ "size too big: %d bytes", j));
}
- if (bufsize > 8192)
+ if (bufsize > MAX_BITMAP_BUF_SIZE)
{
- g_writeln("error, compressed size too big: %d bytes", bufsize);
+ LLOGLN(0, ("libxrdp_send_bitmap: error, compressed size "
+ "too big: %d bytes", bufsize));
}
s->p = s->end;
}
- while (total_bufsize < 4096 && i > 0);
+ while (total_bufsize < MAX_BITMAP_BUF_SIZE && i > 0);
+
+ LLOGLN(10, ("libxrdp_send_bitmap: num_updates %d total_bufsize %d",
+ num_updates, total_bufsize));
p_num_updates[0] = num_updates;
p_num_updates[1] = num_updates >> 8;
xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s,
RDP_DATA_PDU_UPDATE);
- if (total_bufsize > 8192)
+ if (total_bufsize > MAX_BITMAP_BUF_SIZE)
{
- g_writeln("error, total compressed size too big: %d bytes",
- total_bufsize);
+ LLOGLN(0, ("libxrdp_send_bitmap: error, total compressed "
+ "size too big: %d bytes", total_bufsize));
}
}
@@ -513,22 +561,30 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
}
else
{
+ LLOGLN(10, ("libxrdp_send_bitmap: no compression"));
total_lines = height;
i = 0;
p = data;
- if (line_size > 0 && total_lines > 0)
+ if (line_bytes > 0 && total_lines > 0)
{
while (i < total_lines)
{
- lines_sending = 4096 / (line_size + e * Bpp);
+
+ lines_sending = (MAX_BITMAP_BUF_SIZE - 100) / line_pad_bytes;
if (i + lines_sending > total_lines)
{
lines_sending = total_lines - i;
}
- p = p + line_size * lines_sending;
+ if (lines_sending == 0)
+ {
+ LLOGLN(0, ("libxrdp_send_bitmap: error, lines_sending == zero"));
+ break;
+ }
+
+ p += server_line_bytes * lines_sending;
xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s);
out_uint16_le(s, RDP_UPDATE_BITMAP);
out_uint16_le(s, 1); /* num updates */
@@ -540,14 +596,58 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
out_uint16_le(s, lines_sending);
out_uint16_le(s, bpp); /* bpp */
out_uint16_le(s, 0); /* compress */
- out_uint16_le(s, (line_size + e * Bpp) * lines_sending); /* bufsize */
+ out_uint16_le(s, line_pad_bytes * lines_sending); /* bufsize */
q = p;
- for (j = 0; j < lines_sending; j++)
+ switch (bpp)
{
- q = q - line_size;
- out_uint8a(s, q, line_size); /* B_ENDIAN doesn't work here, todo */
- out_uint8s(s, e * Bpp);
+ case 8:
+ for (j = 0; j < lines_sending; j++)
+ {
+ q = q - line_bytes;
+ out_uint8a(s, q, line_bytes);
+ out_uint8s(s, e);
+ }
+ break;
+ case 15:
+ case 16:
+ for (j = 0; j < lines_sending; j++)
+ {
+ q = q - server_line_bytes;
+ for (k = 0; k < width; k++)
+ {
+ pixel = *((tui16*)(q + k * 2));
+ out_uint16_le(s, pixel);
+ }
+ out_uint8s(s, e * 2);
+ }
+ break;
+ case 24:
+ for (j = 0; j < lines_sending; j++)
+ {
+ q = q - server_line_bytes;
+ for (k = 0; k < width; k++)
+ {
+ pixel = *((tui32*)(q + k * 4));
+ out_uint8(s, pixel);
+ out_uint8(s, pixel >> 8);
+ out_uint8(s, pixel >> 16);
+ }
+ out_uint8s(s, e * 3);
+ }
+ break;
+ case 32:
+ for (j = 0; j < lines_sending; j++)
+ {
+ q = q - server_line_bytes;
+ for (k = 0; k < width; k++)
+ {
+ pixel = *((int*)(q + k * 4));
+ out_uint32_le(s, pixel);
+ }
+ out_uint8s(s, e * 4);
+ }
+ break;
}
s_mark_end(s);
@@ -1142,7 +1242,7 @@ libxrdp_send_to_channel(struct xrdp_session *session, int channel_id,
if (xrdp_channel_send(chan, s, channel_id, total_data_len, flags) != 0)
{
- g_writeln("Debug - data NOT sent to channel");
+ g_writeln("libxrdp_send_to_channel: error, server channel data NOT sent to client channel");
free_stream(s);
return 1;
}
@@ -1332,13 +1432,13 @@ libxrdp_fastpath_send_surface(struct xrdp_session *session,
s->rdp_hdr = s->sec_hdr + sec_bytes;
s->end = data_pad + pad_bytes + data_bytes;
s->p = s->data + (rdp_bytes + sec_bytes);
- /* TS_SURFCMD_SET_SURF_BITS */
- out_uint16_le(s, 0x0001); /* CMDTYPE_SET_SURFACE_BITS */
+ /* TS_SURFCMD_STREAM_SURF_BITS */
+ out_uint16_le(s, CMDTYPE_STREAM_SURFACE_BITS);
out_uint16_le(s, destLeft);
out_uint16_le(s, destTop);
out_uint16_le(s, destRight);
out_uint16_le(s, destBottom);
- /* TS_ BITMAP_DATA_EX */
+ /* TS_BITMAP_DATA_EX */
out_uint8(s, bpp);
out_uint8(s, 0);
out_uint8(s, 0);
diff --git a/libxrdp/xrdp_bitmap32_compress.c b/libxrdp/xrdp_bitmap32_compress.c
index 083c4409..daec9f28 100644
--- a/libxrdp/xrdp_bitmap32_compress.c
+++ b/libxrdp/xrdp_bitmap32_compress.c
@@ -107,7 +107,7 @@ fsplit3(char *in_data, int start_line, int width, int e,
}
start_line--;
cy++;
- if (out_index > 64 * 64)
+ if (out_index + width + e > 64 * 64)
{
break;
}
@@ -195,7 +195,7 @@ fsplit4(char *in_data, int start_line, int width, int e,
}
start_line--;
cy++;
- if (out_index > 64 * 64)
+ if (out_index + width + e > 64 * 64)
{
break;
}
@@ -422,6 +422,7 @@ xrdp_bitmap32_compress(char *in_data, int width, int height,
char *sr_data;
char *sg_data;
char *sb_data;
+ char *hold_p;
int a_bytes;
int r_bytes;
int g_bytes;
@@ -449,6 +450,7 @@ xrdp_bitmap32_compress(char *in_data, int width, int height,
r_data = a_data + max_bytes;
g_data = r_data + max_bytes;
b_data = g_data + max_bytes;
+ hold_p = s->p;
if (header & FLAGS_NOALPHA)
{
@@ -459,35 +461,44 @@ xrdp_bitmap32_compress(char *in_data, int width, int height,
fdelta(sr_data, r_data, cx, cy);
fdelta(sg_data, g_data, cx, cy);
fdelta(sb_data, b_data, cx, cy);
- out_uint8(s, header);
- r_bytes = fpack(r_data, cx, cy, s);
- g_bytes = fpack(g_data, cx, cy, s);
- b_bytes = fpack(b_data, cx, cy, s);
- total_bytes = r_bytes + g_bytes + b_bytes;
- if (1 + total_bytes > byte_limit)
+ while (cy > 0)
{
- /* failed */
- LLOGLN(0, ("xrdp_bitmap32_compress: too big, rgb "
- "bytes %d %d %d total_bytes %d cx %d cy %d "
- "byte_limit %d", r_bytes, g_bytes, b_bytes,
- total_bytes, cx, cy, byte_limit));
- return 0;
- }
- max_bytes = cx * cy * 3;
- if (total_bytes > max_bytes)
- {
- /* raw is better */
- LLOGLN(10, ("xrdp_bitmap32_compress: too big, rgb "
- "bytes %d %d %d total_bytes %d cx %d cy %d "
- "max_bytes %d", r_bytes, g_bytes, b_bytes,
- total_bytes, cx, cy, max_bytes));
- init_stream(s, 0);
- foutraw3(s, cx * cy, FLAGS_NOALPHA, sr_data, sg_data, sb_data);
+ s->p = hold_p;
+ out_uint8(s, header);
+ r_bytes = fpack(r_data, cx, cy, s);
+ g_bytes = fpack(g_data, cx, cy, s);
+ b_bytes = fpack(b_data, cx, cy, s);
+ max_bytes = cx * cy * 3;
+ total_bytes = r_bytes + g_bytes + b_bytes;
+ if (total_bytes > max_bytes)
+ {
+ if (2 + max_bytes <= byte_limit)
+ {
+ s->p = hold_p;
+ foutraw3(s, cx * cy, FLAGS_NOALPHA, sr_data, sg_data, sb_data);
+ break;
+ }
+ }
+ if (1 + total_bytes <= byte_limit)
+ {
+ break;
+ }
+ cy--;
}
}
else
{
- foutraw3(s, cx * cy, FLAGS_NOALPHA, sr_data, sg_data, sb_data);
+ while (cy > 0)
+ {
+ max_bytes = cx * cy * 3;
+ if (2 + max_bytes <= byte_limit)
+ {
+ s->p = hold_p;
+ foutraw3(s, cx * cy, FLAGS_NOALPHA, sr_data, sg_data, sb_data);
+ break;
+ }
+ cy--;
+ }
}
}
else
@@ -500,36 +511,45 @@ xrdp_bitmap32_compress(char *in_data, int width, int height,
fdelta(sr_data, r_data, cx, cy);
fdelta(sg_data, g_data, cx, cy);
fdelta(sb_data, b_data, cx, cy);
- out_uint8(s, header);
- a_bytes = fpack(a_data, cx, cy, s);
- r_bytes = fpack(r_data, cx, cy, s);
- g_bytes = fpack(g_data, cx, cy, s);
- b_bytes = fpack(b_data, cx, cy, s);
- max_bytes = cx * cy * 4;
- total_bytes = a_bytes + r_bytes + g_bytes + b_bytes;
- if (1 + total_bytes > byte_limit)
+ while (cy > 0)
{
- /* failed */
- LLOGLN(0, ("xrdp_bitmap32_compress: too big, argb "
- "bytes %d %d %d %d total_bytes %d cx %d cy %d "
- "byte_limit %d", a_bytes, r_bytes, g_bytes, b_bytes,
- total_bytes, cx, cy, byte_limit));
- return 0;
- }
- if (total_bytes > max_bytes)
- {
- /* raw is better */
- LLOGLN(10, ("xrdp_bitmap32_compress: too big, argb "
- "bytes %d %d %d %d total_bytes %d cx %d cy %d "
- "max_bytes %d", a_bytes, r_bytes, g_bytes, b_bytes,
- total_bytes, cx, cy, max_bytes));
- init_stream(s, 0);
- foutraw4(s, cx * cy, 0, sa_data, sr_data, sg_data, sb_data);
+ s->p = hold_p;
+ out_uint8(s, header);
+ a_bytes = fpack(a_data, cx, cy, s);
+ r_bytes = fpack(r_data, cx, cy, s);
+ g_bytes = fpack(g_data, cx, cy, s);
+ b_bytes = fpack(b_data, cx, cy, s);
+ max_bytes = cx * cy * 4;
+ total_bytes = a_bytes + r_bytes + g_bytes + b_bytes;
+ if (total_bytes > max_bytes)
+ {
+ if (2 + max_bytes <= byte_limit)
+ {
+ s->p = hold_p;
+ foutraw4(s, cx * cy, 0, sa_data, sr_data, sg_data, sb_data);
+ break;
+ }
+ }
+ if (1 + total_bytes <= byte_limit)
+ {
+ break;
+ }
+ cy--;
}
}
else
{
- foutraw4(s, cx * cy, 0, sa_data, sr_data, sg_data, sb_data);
+ while (cy > 0)
+ {
+ max_bytes = cx * cy * 4;
+ if (2 + max_bytes <= byte_limit)
+ {
+ s->p = hold_p;
+ foutraw4(s, cx * cy, 0, sa_data, sr_data, sg_data, sb_data);
+ break;
+ }
+ cy--;
+ }
}
}
return cy;
diff --git a/libxrdp/xrdp_bitmap_compress.c b/libxrdp/xrdp_bitmap_compress.c
index 03c56f10..56898776 100644
--- a/libxrdp/xrdp_bitmap_compress.c
+++ b/libxrdp/xrdp_bitmap_compress.c
@@ -22,6 +22,8 @@
#include "libxrdp.h"
+#define BC_MAX_BYTES (16 * 1024)
+
/*****************************************************************************/
#define IN_PIXEL8(in_ptr, in_x, in_y, in_w, in_last_pixel, in_pixel); \
do { \
@@ -695,7 +697,7 @@ xrdp_bitmap_compress(char *in_data, int width, int height,
out_count = end;
line = in_data + width * start_line;
- while (start_line >= 0 && out_count < 32768)
+ while (start_line >= 0 && out_count <= BC_MAX_BYTES)
{
i = (s->p - s->data) + count;
@@ -987,7 +989,7 @@ xrdp_bitmap_compress(char *in_data, int width, int height,
out_count = end * 2;
line = in_data + width * start_line * 2;
- while (start_line >= 0 && out_count < 32768)
+ while (start_line >= 0 && out_count <= BC_MAX_BYTES)
{
i = (s->p - s->data) + count * 2;
@@ -1279,7 +1281,7 @@ xrdp_bitmap_compress(char *in_data, int width, int height,
out_count = end * 3;
line = in_data + width * start_line * 4;
- while (start_line >= 0 && out_count < 32768)
+ while (start_line >= 0 && out_count <= BC_MAX_BYTES)
{
i = (s->p - s->data) + count * 3;
diff --git a/libxrdp/xrdp_caps.c b/libxrdp/xrdp_caps.c
index 9dfe6fef..c4ec7b02 100644
--- a/libxrdp/xrdp_caps.c
+++ b/libxrdp/xrdp_caps.c
@@ -74,8 +74,13 @@ xrdp_caps_process_general(struct xrdp_rdp *self, struct stream *s,
g_writeln("xrdp_caps_process_general: error");
return 1;
}
- in_uint8s(s, 10);
- in_uint16_le(s, extraFlags);
+
+ in_uint16_le(s, self->client_info.client_os_major); /* osMajorType (2 bytes) */
+ in_uint16_le(s, self->client_info.client_os_minor); /* osMinorType (2 bytes) */
+ in_uint8s(s, 6);
+ in_uint16_le(s, extraFlags); /* extraFlags (2 bytes) */
+
+ self->client_info.op1 = extraFlags & NO_BITMAP_COMPRESSION_HDR;
/* use_compact_packets is pretty much 'use rdp5' */
self->client_info.use_compact_packets = (extraFlags != 0);
/* op2 is a boolean to use compact bitmap headers in bitmap cache */
@@ -155,6 +160,15 @@ xrdp_caps_process_order(struct xrdp_rdp *self, struct stream *s,
DEBUG(("desktop cache size %d", i));
in_uint8s(s, 4); /* Unknown */
in_uint8s(s, 4); /* Unknown */
+
+ /* 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]))
+ {
+ g_writeln("xrdp_caps_process_order: not enough orders supported by client, using painter.");
+ self->client_info.no_orders_supported = 1;
+ }
+
return 0;
}
@@ -453,7 +467,7 @@ xrdp_caps_process_codecs(struct xrdp_rdp *self, struct stream *s, int len)
if (g_memcmp(codec_guid, XR_CODEC_GUID_NSCODEC, 16) == 0)
{
- g_writeln("xrdp_caps_process_codecs: nscodec codec id %d prop len %d",
+ g_writeln("xrdp_caps_process_codecs: nscodec, codec id %d, properties len %d",
codec_id, codec_properties_length);
self->client_info.ns_codec_id = codec_id;
i1 = MIN(64, codec_properties_length);
@@ -462,7 +476,7 @@ xrdp_caps_process_codecs(struct xrdp_rdp *self, struct stream *s, int len)
}
else if (g_memcmp(codec_guid, XR_CODEC_GUID_REMOTEFX, 16) == 0)
{
- g_writeln("xrdp_caps_process_codecs: rfx codec id %d prop len %d",
+ g_writeln("xrdp_caps_process_codecs: RemoteFX, codec id %d, properties len %d",
codec_id, codec_properties_length);
self->client_info.rfx_codec_id = codec_id;
i1 = MIN(64, codec_properties_length);
@@ -471,7 +485,7 @@ xrdp_caps_process_codecs(struct xrdp_rdp *self, struct stream *s, int len)
}
else if (g_memcmp(codec_guid, XR_CODEC_GUID_JPEG, 16) == 0)
{
- g_writeln("xrdp_caps_process_codecs: jpeg codec id %d prop len %d",
+ g_writeln("xrdp_caps_process_codecs: jpeg, codec id %d, properties len %d",
codec_id, codec_properties_length);
self->client_info.jpeg_codec_id = codec_id;
i1 = MIN(64, codec_properties_length);
@@ -488,7 +502,7 @@ xrdp_caps_process_codecs(struct xrdp_rdp *self, struct stream *s, int len)
}
else if (g_memcmp(codec_guid, XR_CODEC_GUID_H264, 16) == 0)
{
- g_writeln("xrdp_caps_process_codecs: h264 codec id %d prop len %d",
+ g_writeln("xrdp_caps_process_codecs: h264, codec id %d, properties len %d",
codec_id, codec_properties_length);
self->client_info.h264_codec_id = codec_id;
i1 = MIN(64, codec_properties_length);
@@ -525,11 +539,29 @@ xrdp_caps_process_frame_ack(struct xrdp_rdp *self, struct stream *s, int len)
g_writeln("xrdp_caps_process_frame_ack:");
self->client_info.use_frame_acks = 1;
in_uint32_le(s, self->client_info.max_unacknowledged_frame_count);
+ if (self->client_info.max_unacknowledged_frame_count < 0)
+ {
+ g_writeln(" invalid max_unacknowledged_frame_count value (%d), setting to 0",
+ self->client_info.max_unacknowledged_frame_count);
+ self->client_info.max_unacknowledged_frame_count = 0;
+ }
g_writeln(" max_unacknowledged_frame_count %d", self->client_info.max_unacknowledged_frame_count);
return 0;
}
/*****************************************************************************/
+static int APP_CC
+xrdp_caps_process_surface_cmds(struct xrdp_rdp *self, struct stream *s, int len)
+{
+ int cmdFlags;
+ g_writeln("xrdp_caps_process_surface_cmds:");
+ in_uint32_le(s, cmdFlags);
+ in_uint8s(s, 4); /* reserved */
+ g_writeln(" cmdFlags 0x%08x", cmdFlags);
+ return 0;
+}
+
+/*****************************************************************************/
int APP_CC
xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
{
@@ -655,6 +687,9 @@ xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
case 0x001E: /* CAPSSETTYPE_FRAME_ACKNOWLEDGE */
xrdp_caps_process_frame_ack(self, s, len);
break;
+ case RDP_CAPSET_SURFCMDS: /* CAPSETTYPE_SURFACE_COMMANDS */
+ xrdp_caps_process_surface_cmds(self, s, len);
+ break;
default:
g_writeln("unknown in xrdp_caps_process_confirm_active %d", type);
break;
@@ -663,6 +698,17 @@ xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
s->p = p + len + 4;
}
+ if (self->client_info.no_orders_supported &&
+ (self->client_info.offscreen_support_level != 0))
+ {
+ g_writeln("xrdp_caps_process_confirm_active: not enough orders "
+ "supported by client, client wants off screen bitmap but "
+ "offscreen bitmaps disabled");
+ self->client_info.offscreen_support_level = 0;
+ self->client_info.offscreen_cache_size = 0;
+ self->client_info.offscreen_cache_entries = 0;
+ }
+
DEBUG(("out xrdp_caps_process_confirm_active"));
return 0;
}
@@ -823,22 +869,30 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
codec_caps_count++;
out_uint8a(s, XR_CODEC_GUID_NSCODEC, 16);
out_uint8(s, 1); /* codec id, must be 1 */
- out_uint16_le(s, 3);
+ out_uint16_le(s, 3); /* codecPropertiesLength */
out_uint8(s, 0x01); /* fAllowDynamicFidelity */
out_uint8(s, 0x01); /* fAllowSubsampling */
out_uint8(s, 0x03); /* colorLossLevel */
+#if defined(XRDP_RFXCODEC) || defined(XRDP_NEUTRINORDP)
/* remotefx */
codec_caps_count++;
out_uint8a(s, XR_CODEC_GUID_REMOTEFX, 16);
out_uint8(s, 0); /* codec id, client sets */
- out_uint16_le(s, 256);
- out_uint8s(s, 256);
+ out_uint16_le(s, 4); /* codecPropertiesLength */
+ out_uint32_le(s, 0); /* reserved */
+ /* 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 */
+#endif
/* jpeg */
codec_caps_count++;
out_uint8a(s, XR_CODEC_GUID_JPEG, 16);
out_uint8(s, 0); /* codec id, client sets */
- out_uint16_le(s, 1); /* ext length */
- out_uint8(s, 75);
+ out_uint16_le(s, 1); /* codecPropertiesLength */
+ out_uint8(s, 75); /* jpeg compression ratio */
/* calculate and set size and count */
codec_caps_size = (int)(s->p - codec_caps_size_ptr);
codec_caps_size += 2; /* 2 bytes for RDP_CAPSET_BMPCODECS above */
@@ -866,16 +920,10 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
out_uint16_le(s, RDP_CAPSET_INPUT); /* 13(0xd) */
out_uint16_le(s, RDP_CAPLEN_INPUT); /* 88(0x58) */
- /* INPUT_FLAG_SCANCODES 0x0001
- INPUT_FLAG_MOUSEX 0x0004
- INPUT_FLAG_FASTPATH_INPUT 0x0008
- INPUT_FLAG_FASTPATH_INPUT2 0x0020 */
- flags = 0x0001 | 0x0004;
+ flags = INPUT_FLAG_SCANCODES | INPUT_FLAG_MOUSEX | INPUT_FLAG_UNICODE;
if (self->client_info.use_fast_path & 2)
{
- /* 0x0008 INPUT_FLAG_FASTPATH_INPUT */
- /* 0x0020 INPUT_FLAG_FASTPATH_INPUT2 */
- flags |= 0x0008 | 0x0020;
+ flags |= INPUT_FLAG_FASTPATH_INPUT | INPUT_FLAG_FASTPATH_INPUT2;
}
out_uint16_le(s, flags);
out_uint8s(s, 82);
@@ -901,19 +949,29 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
out_uint16_le(s, 5);
out_uint8(s, 0); /* client sets */
- if (self->client_info.use_fast_path & 1) /* fastpath output on */
+ if (self->client_info.use_fast_path & FASTPATH_OUTPUT_SUPPORTED) /* fastpath output on */
{
+ /* multifragment update */
caps_count++;
- out_uint16_le(s, 0x001A); /* 26 CAPSETTYPE_MULTIFRAGMENTUPDATE */
- out_uint16_le(s, 8);
+ out_uint16_le(s, RDP_CAPSET_MULTIFRAGMENT); /* 26 CAPSETTYPE_MULTIFRAGMENTUPDATE */
+ out_uint16_le(s, RDP_CAPLEN_MULTIFRAGMENT);
out_uint32_le(s, 3 * 1024 * 1024); /* 3MB */
- }
- /* frame acks */
- caps_count++;
- out_uint16_le(s, 0x001E); /* CAPSETTYPE_FRAME_ACKNOWLEDGE */
- out_uint16_le(s, 8);
- out_uint32_le(s, 2); /* 2 frames in flight */
+ /* frame acks */
+ caps_count++;
+ out_uint16_le(s, RDP_CAPSET_FRAME_ACKNOWLEDGE); /* CAPSETTYPE_FRAME_ACKNOWLEDGE */
+ out_uint16_le(s, RDP_CAPLEN_FRAME_ACKNOWLEDGE);
+ out_uint32_le(s, 2); /* 2 frames in flight */
+
+ /* surface commands */
+ caps_count++;
+ out_uint16_le(s, RDP_CAPSET_SURFCMDS); /* CAPSETTYPE_SURFACE_COMMANDS */
+ out_uint16_le(s, RDP_CAPLEN_SURFCMDS); /* lengthCapability */
+ out_uint32_le(s, (SURFCMDS_SETSURFACEBITS |
+ SURFCMDS_FRAMEMARKER |
+ SURFCMDS_STREAMSUFRACEBITS)); /* cmdFlags */
+ out_uint32_le(s, 0); /* reserved */
+ }
out_uint8s(s, 4); /* pad */
diff --git a/libxrdp/xrdp_fastpath.c b/libxrdp/xrdp_fastpath.c
index 008c8289..33e9c9d0 100644
--- a/libxrdp/xrdp_fastpath.c
+++ b/libxrdp/xrdp_fastpath.c
@@ -265,12 +265,30 @@ static int APP_CC
xrdp_fastpath_process_EVENT_UNICODE(struct xrdp_fastpath *self,
int eventFlags, struct stream *s)
{
- if (!s_check_rem(s, 2))
- {
- return 1;
- }
- in_uint8s(s, 2);
- return 0;
+ int flags;
+ int code;
+
+ flags = 0;
+ if (!s_check_rem(s, 2))
+ {
+ return 1;
+ }
+ in_uint16_le(s, code); /* unicode (2 byte) */
+ if (eventFlags & FASTPATH_INPUT_KBDFLAGS_RELEASE)
+ {
+ flags |= KBD_FLAG_UP;
+ }
+ else
+ {
+ flags |= KBD_FLAG_DOWN;
+ }
+ if (eventFlags & FASTPATH_INPUT_KBDFLAGS_EXTENDED)
+ {
+ flags |= KBD_FLAG_EXT;
+ }
+ xrdp_fastpath_session_callback(self, RDP_INPUT_UNICODE,
+ code, 0, flags, 0);
+ return 0;
}
/*****************************************************************************/
diff --git a/libxrdp/xrdp_iso.c b/libxrdp/xrdp_iso.c
index fa7a3f1a..b89e1616 100644
--- a/libxrdp/xrdp_iso.c
+++ b/libxrdp/xrdp_iso.c
@@ -20,6 +20,7 @@
*/
#include "libxrdp.h"
+#include "log.h"
#define LOG_LEVEL 1
#define LLOG(_level, _args) \
@@ -97,7 +98,9 @@ xrdp_iso_negotiate_security(struct xrdp_iso *self)
case PROTOCOL_HYBRID:
case PROTOCOL_HYBRID_EX:
default:
- if (self->requestedProtocol & PROTOCOL_SSL)
+ if ((self->requestedProtocol & PROTOCOL_SSL) &&
+ g_file_exist(client_info->certificate) &&
+ g_file_exist(client_info->key_file))
{
/* that's a patch since we don't support CredSSP for now */
self->selectedProtocol = PROTOCOL_SSL;
@@ -109,8 +112,8 @@ xrdp_iso_negotiate_security(struct xrdp_iso *self)
break;
}
- LLOGLN(10, ("xrdp_iso_negotiate_security: server security layer %d , client security layer %d",
- self->selectedProtocol, self->requestedProtocol));
+ log_message(LOG_LEVEL_DEBUG, "Security layer: requested %d, selected %d",
+ self->requestedProtocol, self->selectedProtocol);
return rv;
}
diff --git a/libxrdp/xrdp_jpeg_compress.c b/libxrdp/xrdp_jpeg_compress.c
index 27c31639..d337af1b 100644
--- a/libxrdp/xrdp_jpeg_compress.c
+++ b/libxrdp/xrdp_jpeg_compress.c
@@ -28,6 +28,7 @@
#include <stdlib.h>
#include <string.h>
#include <turbojpeg.h>
+#include "log.h"
/*****************************************************************************/
int APP_CC
@@ -81,10 +82,13 @@ xrdp_jpeg_compress(void *handle, char *in_data, int width, int height,
*dst32 = pixel;
dst32++;
}
- for (i = 0; i < e; i++)
+ if (width > 0)
{
- *dst32 = pixel;
- dst32++;
+ for (i = 0; i < e; i++)
+ {
+ *dst32 = pixel;
+ dst32++;
+ }
}
}
src_buf = (unsigned char *) temp_buf;
@@ -93,6 +97,13 @@ xrdp_jpeg_compress(void *handle, char *in_data, int width, int height,
error = tjCompress(tj_han, src_buf, width + e, (width + e) * 4, height,
TJPF_XBGR, dst_buf, &cdata_bytes,
TJSAMP_420, quality, 0);
+ if (error != 0)
+ {
+ log_message(LOG_LEVEL_ERROR,
+ "xrdp_jpeg_compress: tjCompress error: %s",
+ tjGetErrorStr());
+ }
+
s->p += cdata_bytes;
g_free(temp_buf);
return height;
@@ -160,17 +171,24 @@ xrdp_codec_jpeg_compress(void *handle,
* TJPF_ARGB no works, zero bytes */
error = tjCompress(tj_han, /* opaque handle */
- src_ptr, /* source buf */
+ (unsigned char *) src_ptr, /* source buf */
cx, /* width of area to compress */
stride, /* pitch */
cy, /* height of area to compress */
TJPF_XBGR, /* pixel size */
- out_data, /* dest buf */
+ (unsigned char *) out_data, /* dest buf */
&lio_len, /* inner_buf length & compressed_size */
TJSAMP_420, /* jpeg sub sample */
quality, /* jpeg quality */
0 /* flags */
);
+ if (error != 0)
+ {
+ log_message(LOG_LEVEL_ERROR,
+ "xrdp_codec_jpeg_compress: tjCompress error: %s",
+ tjGetErrorStr());
+ }
+
*io_len = lio_len;
return height;
}
@@ -213,7 +231,7 @@ xrdp_jpeg_deinit(void *handle)
struct mydata_comp
{
- char *cb;
+ JOCTET *cb;
int cb_bytes;
int total_done;
int overwrite;
@@ -265,8 +283,8 @@ my_term_destination(j_compress_ptr cinfo)
/*****************************************************************************/
static int APP_CC
-jp_do_compress(char *data, int width, int height, int bpp, int quality,
- char *comp_data, int *comp_data_bytes)
+jp_do_compress(JOCTET *data, int width, int height, int bpp, int quality,
+ JOCTET *comp_data, int *comp_data_bytes)
{
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
@@ -336,9 +354,8 @@ jpeg_compress(char *in_data, int width, int height,
struct stream *s, struct stream *temp_s, int bpp,
int byte_limit, int e, int quality)
{
- char *data;
+ JOCTET *data;
tui32 *src32;
- tui16 *src16;
tui8 *dst8;
tui32 pixel;
int red;
@@ -348,7 +365,7 @@ jpeg_compress(char *in_data, int width, int height,
int i;
int cdata_bytes;
- data = temp_s->data;
+ data = (JOCTET *) temp_s->data;
dst8 = data;
if (bpp == 24)
@@ -366,11 +383,14 @@ jpeg_compress(char *in_data, int width, int height,
*(dst8++) = red;
}
- for (i = 0; i < e; i++)
+ if (width > 0)
{
- *(dst8++) = blue;
- *(dst8++) = green;
- *(dst8++) = red;
+ for (i = 0; i < e; i++)
+ {
+ *(dst8++) = blue;
+ *(dst8++) = green;
+ *(dst8++) = red;
+ }
}
}
}
@@ -380,7 +400,8 @@ jpeg_compress(char *in_data, int width, int height,
}
cdata_bytes = byte_limit;
- jp_do_compress(data, width + e, height, 24, quality, s->p, &cdata_bytes);
+ jp_do_compress(data, width + e, height, 24, quality, (JOCTET *) s->p,
+ &cdata_bytes);
s->p += cdata_bytes;
return cdata_bytes;
}
diff --git a/libxrdp/xrdp_orders.c b/libxrdp/xrdp_orders.c
index 18a5ad38..b0c28ed8 100644
--- a/libxrdp/xrdp_orders.c
+++ b/libxrdp/xrdp_orders.c
@@ -2235,6 +2235,11 @@ xrdp_orders_send_raw_bitmap(struct xrdp_orders *self,
Bpp = (bpp + 7) / 8;
bufsize = (width + e) * height * Bpp;
+ while (bufsize + 16 > MAX_ORDERS_SIZE)
+ {
+ height--;
+ bufsize = (width + e) * height * Bpp;
+ }
if (xrdp_orders_check(self, bufsize + 16) != 0)
{
return 1;
@@ -2254,33 +2259,58 @@ xrdp_orders_send_raw_bitmap(struct xrdp_orders *self,
out_uint16_le(self->out_s, bufsize);
out_uint16_le(self->out_s, cache_idx);
- for (i = height - 1; i >= 0; i--)
+ if (Bpp == 4)
{
- for (j = 0; j < width; j++)
+ for (i = height - 1; i >= 0; i--)
{
- if (Bpp == 3)
+ for (j = 0; j < width; j++)
{
pixel = GETPIXEL32(data, j, i, width);
out_uint8(self->out_s, pixel);
out_uint8(self->out_s, pixel >> 8);
out_uint8(self->out_s, pixel >> 16);
+ out_uint8(self->out_s, pixel >> 24);
}
- else if (Bpp == 2)
+ out_uint8s(self->out_s, Bpp * e);
+ }
+ }
+ else if (Bpp == 3)
+ {
+ for (i = height - 1; i >= 0; i--)
+ {
+ for (j = 0; j < width; j++)
{
- pixel = GETPIXEL16(data, j, i, width);
+ pixel = GETPIXEL32(data, j, i, width);
out_uint8(self->out_s, pixel);
out_uint8(self->out_s, pixel >> 8);
+ out_uint8(self->out_s, pixel >> 16);
}
- else if (Bpp == 1)
+ out_uint8s(self->out_s, Bpp * e);
+ }
+ }
+ else if (Bpp == 2)
+ {
+ for (i = height - 1; i >= 0; i--)
+ {
+ for (j = 0; j < width; j++)
{
- pixel = GETPIXEL8(data, j, i, width);
+ pixel = GETPIXEL16(data, j, i, width);
out_uint8(self->out_s, pixel);
+ out_uint8(self->out_s, pixel >> 8);
}
+ out_uint8s(self->out_s, Bpp * e);
}
-
- for (j = 0; j < e; j++)
+ }
+ else if (Bpp == 1)
+ {
+ for (i = height - 1; i >= 0; i--)
{
- out_uint8s(self->out_s, Bpp);
+ for (j = 0; j < width; j++)
+ {
+ pixel = GETPIXEL8(data, j, i, width);
+ out_uint8(self->out_s, pixel);
+ }
+ out_uint8s(self->out_s, Bpp * e);
}
}
@@ -2334,20 +2364,19 @@ xrdp_orders_send_bitmap(struct xrdp_orders *self,
if (bpp > 24)
{
lines_sending = xrdp_bitmap32_compress(data, width, height, s,
- bpp, 16384,
+ bpp, MAX_ORDERS_SIZE,
i - 1, temp_s, e, 0x10);
}
else
{
- lines_sending = xrdp_bitmap_compress(data, width, height, s, bpp, 16384,
+ lines_sending = xrdp_bitmap_compress(data, width, height, s,
+ bpp, MAX_ORDERS_SIZE,
i - 1, temp_s, e);
}
if (lines_sending != height)
{
- g_writeln("error in xrdp_orders_send_bitmap, lines_sending(%d) != \
-height(%d)", lines_sending, height);
- return 1;
+ height = lines_sending;
}
bufsize = (int)(s->p - p);
@@ -2458,6 +2487,7 @@ xrdp_orders_send_raw_bitmap2(struct xrdp_orders *self,
int pixel = 0;
int e = 0;
+ g_writeln("xrdp_orders_send_raw_bitmap2:");
if (width > 64)
{
g_writeln("error, width > 64");
@@ -2479,6 +2509,11 @@ xrdp_orders_send_raw_bitmap2(struct xrdp_orders *self,
Bpp = (bpp + 7) / 8;
bufsize = (width + e) * height * Bpp;
+ while (bufsize + 14 > MAX_ORDERS_SIZE)
+ {
+ height--;
+ bufsize = (width + e) * height * Bpp;
+ }
if (xrdp_orders_check(self, bufsize + 14) != 0)
{
return 1;
@@ -2499,7 +2534,7 @@ xrdp_orders_send_raw_bitmap2(struct xrdp_orders *self,
i = cache_idx & 0xff;
out_uint8(self->out_s, i);
- if (1 && Bpp == 3)
+ if (Bpp == 4)
{
for (i = height - 1; i >= 0; i--)
{
@@ -2509,44 +2544,49 @@ xrdp_orders_send_raw_bitmap2(struct xrdp_orders *self,
out_uint8(self->out_s, pixel);
out_uint8(self->out_s, pixel >> 8);
out_uint8(self->out_s, pixel >> 16);
+ out_uint8(self->out_s, pixel >> 24);
}
- for (j = 0; j < e; j++)
- {
- out_uint8s(self->out_s, Bpp);
- }
+ out_uint8s(self->out_s, Bpp * e);
}
}
- else
- {
- for (i = height - 1; i >= 0; i--)
+ else if (Bpp == 3)
{
- for (j = 0; j < width; j++)
+ for (i = height - 1; i >= 0; i--)
{
- if (Bpp == 3)
+ for (j = 0; j < width; j++)
{
pixel = GETPIXEL32(data, j, i, width);
out_uint8(self->out_s, pixel);
out_uint8(self->out_s, pixel >> 8);
out_uint8(self->out_s, pixel >> 16);
}
- else if (Bpp == 2)
+ out_uint8s(self->out_s, Bpp * e);
+ }
+ }
+ else if (Bpp == 2)
+ {
+ for (i = height - 1; i >= 0; i--)
+ {
+ for (j = 0; j < width; j++)
{
pixel = GETPIXEL16(data, j, i, width);
out_uint8(self->out_s, pixel);
out_uint8(self->out_s, pixel >> 8);
}
- else if (Bpp == 1)
+ out_uint8s(self->out_s, Bpp * e);
+ }
+ }
+ else if (Bpp == 1)
+ {
+ for (i = height - 1; i >= 0; i--)
+ {
+ for (j = 0; j < width; j++)
{
pixel = GETPIXEL8(data, j, i, width);
out_uint8(self->out_s, pixel);
}
+ out_uint8s(self->out_s, Bpp * e);
}
-
- for (j = 0; j < e; j++)
- {
- out_uint8s(self->out_s, Bpp);
- }
- }
}
return 0;
@@ -2599,20 +2639,19 @@ xrdp_orders_send_bitmap2(struct xrdp_orders *self,
if (bpp > 24)
{
lines_sending = xrdp_bitmap32_compress(data, width, height, s,
- bpp, 16384,
+ bpp, MAX_ORDERS_SIZE,
i - 1, temp_s, e, 0x10);
}
else
{
- lines_sending = xrdp_bitmap_compress(data, width, height, s, bpp, 16384,
+ lines_sending = xrdp_bitmap_compress(data, width, height, s,
+ bpp, MAX_ORDERS_SIZE,
i - 1, temp_s, e);
}
if (lines_sending != height)
{
- g_writeln("error in xrdp_orders_send_bitmap2, lines_sending(%d) != \
-height(%d)", lines_sending, height);
- return 1;
+ height = lines_sending;
}
bufsize = (int)(s->p - p);
diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c
index 1520cb37..ca82df70 100644
--- a/libxrdp/xrdp_rdp.c
+++ b/libxrdp/xrdp_rdp.c
@@ -105,8 +105,8 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info)
}
else if (g_strcasecmp(item, "allow_channels") == 0)
{
- client_info->channel_code = g_text2bool(value);
- if (client_info->channel_code == 0)
+ client_info->channels_allowed = g_text2bool(value);
+ if (client_info->channels_allowed == 0)
{
log_message(LOG_LEVEL_DEBUG,"Info - All channels are disabled");
}
@@ -182,10 +182,15 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info)
{
client_info->security_layer = PROTOCOL_SSL | PROTOCOL_HYBRID;
}
+ else if (g_strcasecmp(value, "negotiate") == 0)
+ {
+ client_info->security_layer = PROTOCOL_SSL | PROTOCOL_HYBRID | PROTOCOL_HYBRID_EX;
+ }
else
{
- log_message(LOG_LEVEL_ALWAYS,"Warning: Your configured security layer is "
- "undefined, xrdp will negotiate client compatible");
+ log_message(LOG_LEVEL_ERROR, "security_layer=%s is not "
+ "recognized, will use security_layer=negotiate",
+ value);
client_info->security_layer = PROTOCOL_SSL | PROTOCOL_HYBRID | PROTOCOL_HYBRID_EX;
}
}
@@ -777,9 +782,9 @@ xrdp_rdp_send_data_update_sync(struct xrdp_rdp *self)
return 1;
}
out_uint16_le(s, RDP_UPDATE_SYNCHRONIZE);
+ out_uint16_le(s, 0); /* pad */
}
- out_uint16_le(s, 0); /* pad */
s_mark_end(s);
if (self->client_info.use_fast_path & 1) /* fastpath output supported */
diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c
index 06813d25..422acfe2 100644
--- a/libxrdp/xrdp_sec.c
+++ b/libxrdp/xrdp_sec.c
@@ -1829,12 +1829,12 @@ xrdp_sec_process_mcs_data_channels(struct xrdp_sec *self, struct stream *s)
client_info = &(self->rdp_layer->client_info);
- DEBUG(("processing channels, channel_code is %d", client_info->channel_code));
+ DEBUG(("processing channels, channels_allowed is %d", client_info->channels_allowed));
/* this is an option set in xrdp.ini */
- if (client_info->channel_code != 1) /* are channels on? */
+ if (client_info->channels_allowed != 1) /* are channels on? */
{
- g_writeln("Processing channel data from client - The channel is off");
+ g_writeln("xrdp_sec_process_mcs_data_channels: all channels are disabled by configuration");
return 0;
}
@@ -1862,6 +1862,12 @@ xrdp_sec_process_mcs_data_channels(struct xrdp_sec *self, struct stream *s)
return 1;
}
in_uint8a(s, channel_item->name, 8);
+ if (g_strlen(channel_item->name) == 0)
+ {
+ log_message(LOG_LEVEL_WARNING, "xrdp_sec_process_mcs_data_channels: got an empty channel name, ignoring it");
+ g_free(channel_item);
+ continue;
+ }
in_uint32_le(s, channel_item->flags);
channel_item->chanid = MCS_GLOBAL_CHANNEL + (index + 1);
list_add_item(self->mcs_layer->channel_list, (tintptr) channel_item);