summaryrefslogtreecommitdiffstats
path: root/libxrdp
diff options
context:
space:
mode:
Diffstat (limited to 'libxrdp')
-rw-r--r--libxrdp/Makefile.am11
-rw-r--r--libxrdp/libxrdp.c19
-rw-r--r--libxrdp/libxrdp.h44
-rw-r--r--libxrdp/libxrdpinc.h20
-rw-r--r--libxrdp/xrdp_iso.c237
-rw-r--r--libxrdp/xrdp_jpeg_compress.c139
-rw-r--r--libxrdp/xrdp_mcs.c124
-rw-r--r--libxrdp/xrdp_mppc_enc.c29
-rw-r--r--libxrdp/xrdp_orders.c471
-rw-r--r--libxrdp/xrdp_orders_rail.c35
-rw-r--r--libxrdp/xrdp_rdp.c305
-rw-r--r--libxrdp/xrdp_sec.c241
12 files changed, 1491 insertions, 184 deletions
diff --git a/libxrdp/Makefile.am b/libxrdp/Makefile.am
index 4aba9e7e..6564da36 100644
--- a/libxrdp/Makefile.am
+++ b/libxrdp/Makefile.am
@@ -11,15 +11,22 @@ else
EXTRA_DEFINES += -DXRDP_NODEBUG
endif
-if XRDP_FREERDP1
-EXTRA_DEFINES += -DXRDP_FREERDP1
+if XRDP_NEUTRINORDP
+EXTRA_DEFINES += -DXRDP_NEUTRINORDP
EXTRA_LIBS += $(FREERDP_LIBS)
endif
+if XRDP_TJPEG
+EXTRA_DEFINES += -DXRDP_JPEG -DXRDP_TJPEG
+EXTRA_INCLUDES += -I/opt/libjpeg-turbo/include
+EXTRA_FLAGS += -L/opt/libjpeg-turbo/lib -Wl,-rpath -Wl,/opt/libjpeg-turbo/lib
+EXTRA_LIBS += -lturbojpeg
+else
if XRDP_JPEG
EXTRA_DEFINES += -DXRDP_JPEG
EXTRA_LIBS += -ljpeg
endif
+endif
if GOT_PREFIX
EXTRA_INCLUDES += -I$(prefix)/include
diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c
index 15e34e91..e72fa1d0 100644
--- a/libxrdp/libxrdp.c
+++ b/libxrdp/libxrdp.c
@@ -629,6 +629,25 @@ libxrdp_orders_mem_blt(struct xrdp_session *session, int cache_id,
}
/******************************************************************************/
+int DEFAULT_CC
+libxrdp_orders_composite_blt(struct xrdp_session* session, int srcidx,
+ int srcformat, int srcwidth, int srcrepeat,
+ int* srctransform, int mskflags,
+ int mskidx, int mskformat, int mskwidth,
+ int mskrepeat, int op, int srcx, int srcy,
+ int mskx, int msky, int dstx, int dsty,
+ int width, int height, int dstformat,
+ struct xrdp_rect* rect)
+{
+ return xrdp_orders_composite_blt((struct xrdp_orders*)session->orders,
+ srcidx, srcformat, srcwidth, srcrepeat,
+ srctransform, mskflags,
+ mskidx, mskformat, mskwidth, mskrepeat,
+ op, srcx, srcy, mskx, msky, dstx, dsty,
+ width, height, dstformat, rect);
+}
+
+/******************************************************************************/
int EXPORT_CC
libxrdp_orders_text(struct xrdp_session *session,
int font, int flags, int mixmode,
diff --git a/libxrdp/libxrdp.h b/libxrdp/libxrdp.h
index d31edbb4..5bf627b5 100644
--- a/libxrdp/libxrdp.h
+++ b/libxrdp/libxrdp.h
@@ -49,6 +49,8 @@ struct xrdp_iso
{
struct xrdp_mcs* mcs_layer; /* owner */
struct xrdp_tcp* tcp_layer;
+ int requestedProtocol;
+ int selectedProtocol;
};
/* used in mcs */
@@ -99,6 +101,7 @@ struct xrdp_sec
char pub_sig[64];
char pri_exp[64];
int channel_code;
+ int multimon;
};
/* channel */
@@ -197,6 +200,28 @@ struct xrdp_orders_state
int text_y;
int text_len;
char* text_data;
+
+ int com_blt_srcidx; /* RDP_ORDER_COMPOSITE */ /* 2 */
+ int com_blt_srcformat; /* 2 */
+ int com_blt_srcwidth; /* 2 */
+ int com_blt_srcrepeat; /* 1 */
+ int com_blt_srctransform[10]; /* 40 */
+ int com_blt_mskflags; /* 1 */
+ int com_blt_mskidx; /* 2 */
+ int com_blt_mskformat; /* 2 */
+ int com_blt_mskwidth; /* 2 */
+ int com_blt_mskrepeat; /* 1 */
+ int com_blt_op; /* 1 */
+ int com_blt_srcx; /* 2 */
+ int com_blt_srcy; /* 2 */
+ int com_blt_mskx; /* 2 */
+ int com_blt_msky; /* 2 */
+ int com_blt_dstx; /* 2 */
+ int com_blt_dsty; /* 2 */
+ int com_blt_width; /* 2 */
+ int com_blt_height; /* 2 */
+ int com_blt_dstformat; /* 2 */
+
};
/* orders */
@@ -211,6 +236,8 @@ struct xrdp_orders
int order_count;
int order_level; /* inc for every call to xrdp_orders_init */
struct xrdp_orders_state orders_state;
+ void* jpeg_han;
+ int rfx_min_pixel;
};
#define PROTO_RDP_40 1
@@ -285,7 +312,7 @@ xrdp_mcs_disconnect(struct xrdp_mcs* self);
/* xrdp_sec.c */
struct xrdp_sec* APP_CC
xrdp_sec_create(struct xrdp_rdp* owner, struct trans* trans, int crypt_level,
- int channel_code);
+ int channel_code, int multimon);
void APP_CC
xrdp_sec_delete(struct xrdp_sec* self);
int APP_CC
@@ -378,6 +405,15 @@ xrdp_orders_mem_blt(struct xrdp_orders* self, int cache_id,
int rop, int srcx, int srcy,
int cache_idx, struct xrdp_rect* rect);
int APP_CC
+xrdp_orders_composite_blt(struct xrdp_orders* self, int srcidx,
+ int srcformat, int srcwidth,
+ int srcrepeat, int* srctransform, int mskflags,
+ int mskidx, int mskformat, int mskwidth,
+ int mskrepeat, int op, int srcx, int srcy,
+ int mskx, int msky, int dstx, int dsty,
+ int width, int height, int dstformat,
+ struct xrdp_rect* rect);
+int APP_CC
xrdp_orders_text(struct xrdp_orders* self,
int font, int flags, int mixmode,
int fg_color, int bg_color,
@@ -431,10 +467,14 @@ xrdp_bitmap_compress(char* in_data, int width, int height,
int start_line, struct stream* temp_s,
int e);
int APP_CC
-xrdp_jpeg_compress(char* in_data, int width, int height,
+xrdp_jpeg_compress(void *handle, char* in_data, int width, int height,
struct stream* s, int bpp, int byte_limit,
int start_line, struct stream* temp_s,
int e, int quality);
+void *APP_CC
+xrdp_jpeg_init(void);
+int APP_CC
+xrdp_jpeg_deinit(void *handle);
/* xrdp_channel.c */
struct xrdp_channel* APP_CC
diff --git a/libxrdp/libxrdpinc.h b/libxrdp/libxrdpinc.h
index b971204e..e5f52a05 100644
--- a/libxrdp/libxrdpinc.h
+++ b/libxrdp/libxrdpinc.h
@@ -40,13 +40,15 @@ struct xrdp_pen
int color;
};
+/* 2.2.2.2.1.2.5.1 Cache Glyph Data (TS_CACHE_GLYPH_DATA) */
struct xrdp_font_char
{
- int offset;
- int baseline;
- int width;
- int height;
+ int offset; /* x */
+ int baseline; /* y */
+ int width; /* cx */
+ int height; /* cy */
int incby;
+ int bpp;
char* data;
};
@@ -128,6 +130,16 @@ libxrdp_orders_mem_blt(struct xrdp_session* session, int cache_id,
int rop, int srcx, int srcy,
int cache_idx, struct xrdp_rect* rect);
int DEFAULT_CC
+libxrdp_orders_composite_blt(struct xrdp_session* session, int srcidx,
+ int srcformat, int srcwidth, int srcrepeat,
+ int* srctransform, int mskflags,
+ int mskidx, int mskformat, int mskwidth,
+ int mskrepeat, int op, int srcx, int srcy,
+ int mskx, int msky, int dstx, int dsty,
+ int width, int height, int dstformat,
+ struct xrdp_rect* rect);
+
+int DEFAULT_CC
libxrdp_orders_text(struct xrdp_session* session,
int font, int flags, int mixmode,
int fg_color, int bg_color,
diff --git a/libxrdp/xrdp_iso.c b/libxrdp/xrdp_iso.c
index d851c1bb..69c242d3 100644
--- a/libxrdp/xrdp_iso.c
+++ b/libxrdp/xrdp_iso.c
@@ -2,6 +2,7 @@
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
+ * Copyright (C) Idan Freiberg 2013
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -50,12 +51,49 @@ xrdp_iso_delete(struct xrdp_iso *self)
/*****************************************************************************/
/* returns error */
static int APP_CC
-xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code)
+xrdp_iso_recv_rdpnegreq(struct xrdp_iso *self, struct stream *s)
{
- int ver;
+ int flags;
int len;
- *code = 0;
+ DEBUG((" in xrdp_iso_recv_rdpnegreq"));
+
+ in_uint8(s, flags);
+ if (flags != 0x0)
+ {
+ DEBUG((" xrdp_iso_recv_rdpnegreq: flags: %x",flags));
+ return 1;
+ }
+
+ in_uint16_le(s, len);
+ if (len != 8) // fixed length
+ {
+ DEBUG((" xrdp_iso_recv_rdpnegreq: length: %x",len));
+ return 1;
+ }
+
+ in_uint32_le(s, self->requestedProtocol);
+
+ //TODO: think of protocol verification logic
+// if (requestedProtocol != PROTOCOL_RDP || PROTOCOL_SSL || PROTOCOL_HYBRID || PROTOCOL_HYBRID_EX)
+// {
+// DEBUG((" xrdp_iso_recv_rdpnegreq: wrong requestedProtocol: %x",requestedProtocol));
+// return 1;
+// }
+
+ DEBUG((" out xrdp_iso_recv_rdpnegreq"));
+ return 0;
+}
+/*****************************************************************************/
+/* returns error */
+static int APP_CC
+xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code, int *len)
+{
+ int ver; // TPKT Version
+ int plen; // TPKT PacketLength
+
+ *code = 0; // X.224 Packet Type
+ *len = 0; // X.224 Length Indicator
if (xrdp_tcp_recv(self->tcp_layer, s, 4) != 0)
{
@@ -70,46 +108,64 @@ xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code)
}
in_uint8s(s, 1);
- in_uint16_be(s, len);
+ in_uint16_be(s, plen);
- if (xrdp_tcp_recv(self->tcp_layer, s, len - 4) != 0)
+ if (plen < 4)
{
return 1;
}
- in_uint8s(s, 1);
+ if (xrdp_tcp_recv(self->tcp_layer, s, plen - 4) != 0)
+ {
+ return 1;
+ }
+
+ if (!s_check_rem(s, 2))
+ {
+ return 1;
+ }
+
+ in_uint8(s, *len);
in_uint8(s, *code);
if (*code == ISO_PDU_DT)
{
+ if (!s_check_rem(s, 1))
+ {
+ return 1;
+ }
in_uint8s(s, 1);
}
else
{
+ if (!s_check_rem(s, 5))
+ {
+ return 1;
+ }
in_uint8s(s, 5);
}
return 0;
}
-
/*****************************************************************************/
/* returns error */
int APP_CC
xrdp_iso_recv(struct xrdp_iso *self, struct stream *s)
{
int code;
+ int len;
DEBUG((" in xrdp_iso_recv"));
- if (xrdp_iso_recv_msg(self, s, &code) != 0)
+ if (xrdp_iso_recv_msg(self, s, &code, &len) != 0)
{
DEBUG((" out xrdp_iso_recv xrdp_iso_recv_msg return non zero"));
return 1;
}
- if (code != ISO_PDU_DT)
+ if (code != ISO_PDU_DT || len != 2)
{
- DEBUG((" out xrdp_iso_recv code != ISO_PDU_DT"));
+ DEBUG((" out xrdp_iso_recv code != ISO_PDU_DT or length != 2"));
return 1;
}
@@ -119,21 +175,79 @@ xrdp_iso_recv(struct xrdp_iso *self, struct stream *s)
/*****************************************************************************/
static int APP_CC
-xrdp_iso_send_msg(struct xrdp_iso *self, struct stream *s, int code)
+xrdp_iso_send_rdpnegrsp(struct xrdp_iso *self, struct stream *s, int code)
{
if (xrdp_tcp_init(self->tcp_layer, s) != 0)
{
return 1;
}
- out_uint8(s, 3);
+ /* TPKT HEADER - 4 bytes */
+ out_uint8(s, 3); /* version */
+ out_uint8(s, 0); /* RESERVED */
+ if (self->selectedProtocol != -1)
+ {
+ out_uint16_be(s, 19); /* length */ //rdp negotiation happens.
+ }
+ else
+ {
+ out_uint16_be(s, 11); /* length */ //rdp negotiation doesn't happen.
+ }
+ /* ISO LAYER - X.224 - 7 bytes*/
+ if (self->selectedProtocol != -1)
+ {
+ out_uint8(s, 14); /* length */
+ }
+ else
+ {
+ out_uint8(s, 6); /* length */
+ }
+ out_uint8(s, code); /* SHOULD BE 0xD for CC */
+ out_uint16_be(s, 0);
+ out_uint16_be(s, 0x1234);
out_uint8(s, 0);
- out_uint16_be(s, 11); /* length */
- out_uint8(s, 6);
- out_uint8(s, code);
- out_uint16_le(s, 0);
- out_uint16_le(s, 0);
+ if (self->selectedProtocol != -1)
+ {
+ /* RDP_NEG_RSP - 8 bytes*/
+ out_uint8(s, RDP_NEG_RSP);
+ out_uint8(s, EXTENDED_CLIENT_DATA_SUPPORTED); /* flags */
+ out_uint16_le(s, 8); /* fixed length */
+ out_uint32_le(s, self->selectedProtocol); /* selected protocol */
+ }
+
+ s_mark_end(s);
+
+ if (xrdp_tcp_send(self->tcp_layer, s) != 0)
+ {
+ return 1;
+ }
+
+ return 0;
+}
+/*****************************************************************************/
+static int APP_CC
+xrdp_iso_send_rdpnegfailure(struct xrdp_iso *self, struct stream *s, int code, int failureCode)
+{
+ if (xrdp_tcp_init(self->tcp_layer, s) != 0)
+ {
+ return 1;
+ }
+
+ /* TPKT HEADER - 4 bytes */
+ out_uint8(s, 3); /* version */
+ out_uint8(s, 0); /* RESERVED */
+ out_uint16_be(s, 19); /* length */
+ /* ISO LAYER - X.224 - 7 bytes*/
+ out_uint8(s, 14); /* length */
+ out_uint8(s, code); /* SHOULD BE 0xD for CC */
+ out_uint16_be(s, 0);
+ out_uint16_be(s, 0x1234);
out_uint8(s, 0);
+ /* RDP_NEG_FAILURE - 8 bytes*/
+ out_uint8(s, RDP_NEG_FAILURE);
+ out_uint8(s, 0); /* no flags available */
+ out_uint16_le(s, 8); /* fixed length */
+ out_uint32_le(s, failureCode); /* failure code */
s_mark_end(s);
if (xrdp_tcp_send(self->tcp_layer, s) != 0)
@@ -145,30 +259,111 @@ xrdp_iso_send_msg(struct xrdp_iso *self, struct stream *s, int code)
}
/*****************************************************************************/
+static int APP_CC
+xrdp_iso_send_nego(struct xrdp_iso *self)
+{
+ struct stream *s;
+
+ make_stream(s);
+ init_stream(s, 8192);
+
+ //TODO: negotiation logic here.
+ if (self->requestedProtocol != PROTOCOL_RDP)
+ {
+ // Send RDP_NEG_FAILURE back to client
+ if (xrdp_iso_send_rdpnegfailure(self, s, ISO_PDU_CC,
+ SSL_NOT_ALLOWED_BY_SERVER) != 0)
+ {
+ free_stream(s);
+ return 1;
+ }
+ }
+ else
+ {
+ self->selectedProtocol = PROTOCOL_RDP;
+ // Send RDP_NEG_RSP back to client
+ if (xrdp_iso_send_rdpnegrsp(self, s, ISO_PDU_CC) != 0)
+ {
+ free_stream(s);
+ return 1;
+ }
+ }
+ free_stream(s);
+ return 0;
+}
+
+/*****************************************************************************/
/* returns error */
int APP_CC
xrdp_iso_incoming(struct xrdp_iso *self)
{
int code;
+ int len;
+ int cookie_index;
+ int cc_type;
+ char text[256];
+ char *pend;
struct stream *s;
make_stream(s);
init_stream(s, 8192);
DEBUG((" in xrdp_iso_incoming"));
- if (xrdp_iso_recv_msg(self, s, &code) != 0)
+ if (xrdp_iso_recv_msg(self, s, &code, &len) != 0)
{
+ DEBUG((" in xrdp_iso_recv_msg error!!"));
free_stream(s);
return 1;
}
- if (code != ISO_PDU_CR)
+ if ((code != ISO_PDU_CR) || (len < 6))
{
free_stream(s);
return 1;
}
- if (xrdp_iso_send_msg(self, s, ISO_PDU_CC) != 0)
+ self->selectedProtocol = -1;
+ self->requestedProtocol = PROTOCOL_RDP;
+
+ pend = s->p + (len - 6);
+ cookie_index = 0;
+ while (s->p < pend)
+ {
+ in_uint8(s, cc_type);
+ switch (cc_type)
+ {
+ default:
+ break;
+ case RDP_NEG_REQ: /* rdpNegReq 1 */
+ if (xrdp_iso_recv_rdpnegreq(self, s) != 0)
+ {
+ free_stream(s);
+ return 1;
+ }
+ break;
+ case RDP_CORRELATION_INFO: /* rdpCorrelationInfo 6 */
+ // TODO
+ in_uint8s(s, 1 + 2 + 16 + 16);
+ break;
+ case 'C': /* Cookie routingToken */
+ while (s->p < pend)
+ {
+ text[cookie_index] = cc_type;
+ cookie_index++;
+ if ((s->p[0] == 0x0D) && (s->p[1] == 0x0A))
+ {
+ in_uint8s(s, 2);
+ text[cookie_index] = 0;
+ cookie_index = 0;
+ break;
+ }
+ in_uint8(s, cc_type);
+ }
+ break;
+ }
+ }
+
+ if (xrdp_iso_send_nego(self) != 0)
{
free_stream(s);
return 1;
@@ -198,7 +393,7 @@ xrdp_iso_send(struct xrdp_iso *self, struct stream *s)
DEBUG((" in xrdp_iso_send"));
s_pop_layer(s, iso_hdr);
- len = s->end - s->p;
+ len = (int)(s->end - s->p);
out_uint8(s, 3);
out_uint8(s, 0);
out_uint16_be(s, len);
diff --git a/libxrdp/xrdp_jpeg_compress.c b/libxrdp/xrdp_jpeg_compress.c
index 82a816a0..a41bd1cf 100644
--- a/libxrdp/xrdp_jpeg_compress.c
+++ b/libxrdp/xrdp_jpeg_compress.c
@@ -20,7 +20,112 @@
#include "libxrdp.h"
-#if defined(XRDP_JPEG)
+#if defined(XRDP_TJPEG)
+
+/* turbo jpeg */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <turbojpeg.h>
+
+/*****************************************************************************/
+int APP_CC
+xrdp_jpeg_compress(void *handle, char *in_data, int width, int height,
+ struct stream *s, int bpp, int byte_limit,
+ int start_line, struct stream *temp_s,
+ int e, int quality)
+{
+ int error;
+ int i;
+ int j;
+ unsigned int pixel;
+ unsigned int *src32;
+ unsigned int *dst32;
+ unsigned long cdata_bytes;
+ unsigned char *src_buf;
+ unsigned char *dst_buf;
+ char *temp_buf;
+ tjhandle tj_han;
+
+ if (bpp != 24)
+ {
+ g_writeln("xrdp_jpeg_compress: bpp wrong %d", bpp);
+ return height;
+ }
+ if (handle == 0)
+ {
+ g_writeln("xrdp_jpeg_compress: handle is nil");
+ return height;
+ }
+ tj_han = (tjhandle) handle;
+ cdata_bytes = byte_limit;
+ src_buf = (unsigned char *) in_data;
+ dst_buf = (unsigned char *) (s->p);
+ temp_buf = 0;
+ if (e == 0)
+ {
+ src_buf = (unsigned char*)in_data;
+ }
+ else
+ {
+ temp_buf = (char *) g_malloc((width + e) * height * 4, 0);
+ dst32 = (unsigned int *) temp_buf;
+ src32 = (unsigned int *) in_data;
+ for (j = 0; j < height; j++)
+ {
+ for (i = 0; i < width; i++)
+ {
+ pixel = *src32;
+ src32++;
+ *dst32 = pixel;
+ dst32++;
+ }
+ for (i = 0; i < e; i++)
+ {
+ *dst32 = pixel;
+ dst32++;
+ }
+ }
+ src_buf = (unsigned char *) temp_buf;
+ }
+ dst_buf = (unsigned char*)(s->p);
+ error = tjCompress(tj_han, src_buf, width + e, (width + e) * 4, height,
+ TJPF_XBGR, dst_buf, &cdata_bytes,
+ TJSAMP_420, quality, 0);
+ s->p += cdata_bytes;
+ g_free(temp_buf);
+ return height;
+}
+
+/*****************************************************************************/
+void *APP_CC
+xrdp_jpeg_init(void)
+{
+ tjhandle tj_han;
+
+ tj_han = tjInitCompress();
+ return tj_han;
+}
+
+/*****************************************************************************/
+int APP_CC
+xrdp_jpeg_deinit(void *handle)
+{
+ tjhandle tj_han;
+
+ if (handle == 0)
+ {
+ return 0;
+ }
+ tj_han = (tjhandle) handle;
+ tjDestroy(tj_han);
+ return 0;
+}
+
+#elif defined(XRDP_JPEG)
+
+/* libjpeg */
#include <stdio.h>
#include <stdlib.h>
@@ -205,7 +310,7 @@ jpeg_compress(char *in_data, int width, int height,
/*****************************************************************************/
int APP_CC
-xrdp_jpeg_compress(char *in_data, int width, int height,
+xrdp_jpeg_compress(void *handle, char *in_data, int width, int height,
struct stream *s, int bpp, int byte_limit,
int start_line, struct stream *temp_s,
int e, int quality)
@@ -215,11 +320,25 @@ xrdp_jpeg_compress(char *in_data, int width, int height,
return height;
}
+/*****************************************************************************/
+void *APP_CC
+xrdp_jpeg_init(void)
+{
+ return 0;
+}
+
+/*****************************************************************************/
+int APP_CC
+xrdp_jpeg_deinit(void *handle)
+{
+ return 0;
+}
+
#else
/*****************************************************************************/
int APP_CC
-xrdp_jpeg_compress(char *in_data, int width, int height,
+xrdp_jpeg_compress(void *handle, char *in_data, int width, int height,
struct stream *s, int bpp, int byte_limit,
int start_line, struct stream *temp_s,
int e, int quality)
@@ -227,4 +346,18 @@ xrdp_jpeg_compress(char *in_data, int width, int height,
return height;
}
+/*****************************************************************************/
+void *APP_CC
+xrdp_jpeg_init(void)
+{
+ return 0;
+}
+
+/*****************************************************************************/
+int APP_CC
+xrdp_jpeg_deinit(void *handle)
+{
+ return 0;
+}
+
#endif
diff --git a/libxrdp/xrdp_mcs.c b/libxrdp/xrdp_mcs.c
index 4bf3d025..c145158c 100644
--- a/libxrdp/xrdp_mcs.c
+++ b/libxrdp/xrdp_mcs.c
@@ -66,6 +66,7 @@ xrdp_mcs_delete(struct xrdp_mcs *self)
}
list_delete(self->channel_list);
+
xrdp_iso_delete(self->iso_layer);
/* make sure we get null pointer exception if struct is used again. */
DEBUG(("xrdp_mcs_delete processed"))
@@ -132,6 +133,11 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan)
return 1;
}
+ if (!s_check_rem(s, 1))
+ {
+ return 1;
+ }
+
in_uint8(s, opcode);
appid = opcode >> 2;
@@ -145,6 +151,11 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan)
/* this is channels getting added from the client */
if (appid == MCS_CJRQ)
{
+ if (!s_check_rem(s, 4))
+ {
+ return 1;
+ }
+
in_uint16_be(s, userid);
in_uint16_be(s, chanid);
log_message(LOG_LEVEL_DEBUG,"MCS_CJRQ - channel join request received");
@@ -176,6 +187,11 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan)
return 1;
}
+ if (!s_check_rem(s, 6))
+ {
+ return 1;
+ }
+
in_uint8s(s, 2);
in_uint16_be(s, *chan);
in_uint8s(s, 1);
@@ -183,6 +199,10 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan)
if (len & 0x80)
{
+ if (!s_check_rem(s, 1))
+ {
+ return 1;
+ }
in_uint8s(s, 1);
}
@@ -202,10 +222,18 @@ xrdp_mcs_ber_parse_header(struct xrdp_mcs *self, struct stream *s,
if (tag_val > 0xff)
{
+ if (!s_check_rem(s, 2))
+ {
+ return 1;
+ }
in_uint16_be(s, tag);
}
else
{
+ if (!s_check_rem(s, 1))
+ {
+ return 1;
+ }
in_uint8(s, tag);
}
@@ -214,6 +242,11 @@ xrdp_mcs_ber_parse_header(struct xrdp_mcs *self, struct stream *s,
return 1;
}
+ if (!s_check_rem(s, 1))
+ {
+ return 1;
+ }
+
in_uint8(s, l);
if (l & 0x80)
@@ -223,6 +256,10 @@ xrdp_mcs_ber_parse_header(struct xrdp_mcs *self, struct stream *s,
while (l > 0)
{
+ if (!s_check_rem(s, 1))
+ {
+ return 1;
+ }
in_uint8(s, i);
*len = (*len << 8) | i;
l--;
@@ -255,6 +292,11 @@ xrdp_mcs_parse_domain_params(struct xrdp_mcs *self, struct stream *s)
return 1;
}
+ if ((len < 0) || !s_check_rem(s, len))
+ {
+ return 1;
+ }
+
in_uint8s(s, len);
if (s_check(s))
@@ -276,7 +318,7 @@ xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self)
struct stream *s;
make_stream(s);
- init_stream(s, 8192);
+ init_stream(s, 16 * 1024);
if (xrdp_iso_recv(self->iso_layer, s) != 0)
{
@@ -296,6 +338,12 @@ xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self)
return 1;
}
+ if ((len < 0) || !s_check_rem(s, len))
+ {
+ free_stream(s);
+ return 1;
+ }
+
in_uint8s(s, len);
if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_OCTET_STRING, &len) != 0)
@@ -304,6 +352,12 @@ xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self)
return 1;
}
+ if ((len < 0) || !s_check_rem(s, len))
+ {
+ free_stream(s);
+ return 1;
+ }
+
in_uint8s(s, len);
if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_BOOLEAN, &len) != 0)
@@ -312,6 +366,12 @@ xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self)
return 1;
}
+ if ((len < 0) || !s_check_rem(s, len))
+ {
+ free_stream(s);
+ return 1;
+ }
+
in_uint8s(s, len);
if (xrdp_mcs_parse_domain_params(self, s) != 0)
@@ -338,6 +398,19 @@ xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self)
return 1;
}
+ /* mcs data can not be zero length */
+ if ((len <= 0) || (len > 16 * 1024))
+ {
+ free_stream(s);
+ return 1;
+ }
+
+ if (!s_check_rem(s, len))
+ {
+ free_stream(s);
+ return 1;
+ }
+
/* make a copy of client mcs data */
init_stream(self->client_mcs_data, len);
out_uint8a(self->client_mcs_data, s->p, len);
@@ -364,6 +437,7 @@ xrdp_mcs_recv_edrq(struct xrdp_mcs *self)
int opcode;
struct stream *s;
+ DEBUG((" in xrdp_mcs_recv_edrq"));
make_stream(s);
init_stream(s, 8192);
@@ -372,6 +446,12 @@ xrdp_mcs_recv_edrq(struct xrdp_mcs *self)
free_stream(s);
return 1;
}
+
+ if (!s_check_rem(s, 1))
+ {
+ free_stream(s);
+ return 1;
+ }
in_uint8(s, opcode);
@@ -381,11 +461,22 @@ xrdp_mcs_recv_edrq(struct xrdp_mcs *self)
return 1;
}
+ if (!s_check_rem(s, 4))
+ {
+ free_stream(s);
+ return 1;
+ }
+
in_uint8s(s, 2);
in_uint8s(s, 2);
if (opcode & 2)
{
+ if (!s_check_rem(s, 2))
+ {
+ free_stream(s);
+ return 1;
+ }
in_uint16_be(s, self->userid);
}
@@ -396,6 +487,7 @@ xrdp_mcs_recv_edrq(struct xrdp_mcs *self)
}
free_stream(s);
+ DEBUG((" out xrdp_mcs_recv_edrq"));
return 0;
}
@@ -407,6 +499,7 @@ xrdp_mcs_recv_aurq(struct xrdp_mcs *self)
int opcode;
struct stream *s;
+ DEBUG((" in xrdp_mcs_recv_aurq"));
make_stream(s);
init_stream(s, 8192);
@@ -416,6 +509,12 @@ xrdp_mcs_recv_aurq(struct xrdp_mcs *self)
return 1;
}
+ if (!s_check_rem(s, 1))
+ {
+ free_stream(s);
+ return 1;
+ }
+
in_uint8(s, opcode);
if ((opcode >> 2) != MCS_AURQ)
@@ -426,6 +525,11 @@ xrdp_mcs_recv_aurq(struct xrdp_mcs *self)
if (opcode & 2)
{
+ if (!s_check_rem(s, 2))
+ {
+ free_stream(s);
+ return 1;
+ }
in_uint16_be(s, self->userid);
}
@@ -436,6 +540,7 @@ xrdp_mcs_recv_aurq(struct xrdp_mcs *self)
}
free_stream(s);
+ DEBUG((" out xrdp_mcs_recv_aurq"));
return 0;
}
@@ -491,6 +596,12 @@ xrdp_mcs_recv_cjrq(struct xrdp_mcs *self)
return 1;
}
+ if (!s_check_rem(s, 1))
+ {
+ free_stream(s);
+ return 1;
+ }
+
in_uint8(s, opcode);
if ((opcode >> 2) != MCS_CJRQ)
@@ -499,10 +610,21 @@ xrdp_mcs_recv_cjrq(struct xrdp_mcs *self)
return 1;
}
+ if (!s_check_rem(s, 4))
+ {
+ free_stream(s);
+ return 1;
+ }
+
in_uint8s(s, 4);
if (opcode & 2)
{
+ if (!s_check_rem(s, 2))
+ {
+ free_stream(s);
+ return 1;
+ }
in_uint8s(s, 2);
}
diff --git a/libxrdp/xrdp_mppc_enc.c b/libxrdp/xrdp_mppc_enc.c
index 05aa6bb6..15125d54 100644
--- a/libxrdp/xrdp_mppc_enc.c
+++ b/libxrdp/xrdp_mppc_enc.c
@@ -573,18 +573,21 @@ compress_rdp_5(struct xrdp_mppc_enc *enc, tui8 *srcData, int len)
outputBuffer = enc->outputBuffer;
g_memset(outputBuffer, 0, len);
enc->flags = PACKET_COMPR_TYPE_64K;
+
if (enc->first_pkt)
{
enc->first_pkt = 0;
enc->flagsHold |= PACKET_AT_FRONT;
}
- if ((enc->historyOffset + len) > enc->buf_len)
+ if ((enc->historyOffset + len) >= enc->buf_len)
{
/* historyBuffer cannot hold srcData - rewind it */
enc->historyOffset = 0;
- enc->flagsHold |= PACKET_AT_FRONT;
g_memset(hash_table, 0, enc->buf_len * 2);
+ g_memset(enc->historyBuffer, 0, enc->buf_len); // added
+ enc->first_pkt = 0;
+ enc->flagsHold |= PACKET_AT_FRONT;
}
/* point to next free byte in historyBuffer */
@@ -602,7 +605,7 @@ compress_rdp_5(struct xrdp_mppc_enc *enc, tui8 *srcData, int len)
/* first 2 bytes,because minimum LoM is 3 */
if (historyOffset == 0)
{
- /* encode first two bytes are literals */
+ /* encode first two bytes as literals */
for (x = 0; x < 2; x++)
{
data = *(historyPointer + x);
@@ -974,8 +977,14 @@ compress_rdp_5(struct xrdp_mppc_enc *enc, tui8 *srcData, int len)
/* give up */
enc->historyOffset = 0;
g_memset(hash_table, 0, enc->buf_len * 2);
+ g_memset(enc->historyBuffer, 0, enc->buf_len);
enc->flagsHold |= PACKET_FLUSHED;
enc->first_pkt = 1;
+
+ g_memcpy(enc->outputBuffer, srcData, len);
+ enc->bytes_in_opb = len;
+ enc->flags = 0x81;
+
return 1;
}
else if (opb_index + 1 > len)
@@ -984,8 +993,14 @@ compress_rdp_5(struct xrdp_mppc_enc *enc, tui8 *srcData, int len)
/* give up */
enc->historyOffset = 0;
g_memset(hash_table, 0, enc->buf_len * 2);
+ g_memset(enc->historyBuffer, 0, enc->buf_len);
enc->flagsHold |= PACKET_FLUSHED;
enc->first_pkt = 1;
+
+ g_memcpy(enc->outputBuffer, srcData, len);
+ enc->bytes_in_opb = len;
+ enc->flags = 0x81;
+
return 1;
}
@@ -1000,8 +1015,14 @@ compress_rdp_5(struct xrdp_mppc_enc *enc, tui8 *srcData, int len)
/* give up */
enc->historyOffset = 0;
g_memset(hash_table, 0, enc->buf_len * 2);
+ g_memset(enc->historyBuffer, 0, enc->buf_len);
enc->flagsHold |= PACKET_FLUSHED;
enc->first_pkt = 1;
+
+ g_memcpy(enc->outputBuffer, srcData, len);
+ enc->bytes_in_opb = len;
+ enc->flags = 0x81;
+
return 1;
}
enc->flags |= PACKET_COMPRESSED;
@@ -1011,6 +1032,8 @@ compress_rdp_5(struct xrdp_mppc_enc *enc, tui8 *srcData, int len)
enc->flagsHold = 0;
DLOG(("\n"));
+ //g_writeln("compression ratio: %f", (float) len / (float) enc->bytes_in_opb);
+
return 1;
}
diff --git a/libxrdp/xrdp_orders.c b/libxrdp/xrdp_orders.c
index 29234173..0e2d90d2 100644
--- a/libxrdp/xrdp_orders.c
+++ b/libxrdp/xrdp_orders.c
@@ -20,7 +20,7 @@
#include "libxrdp.h"
-#if defined(XRDP_FREERDP1)
+#if defined(XRDP_NEUTRINORDP)
#include <freerdp/codec/rfx.h>
#endif
@@ -47,6 +47,12 @@ xrdp_orders_create(struct xrdp_session *session, struct xrdp_rdp *rdp_layer)
init_stream(self->out_s, 16384);
self->orders_state.clip_right = 1; /* silly rdp right clip */
self->orders_state.clip_bottom = 1; /* silly rdp bottom clip */
+ self->jpeg_han = xrdp_jpeg_init();
+ self->rfx_min_pixel = rdp_layer->client_info.rfx_min_pixel;
+ if (self->rfx_min_pixel == 0)
+ {
+ self->rfx_min_pixel = 64 * 32;
+ }
return self;
}
@@ -59,6 +65,7 @@ xrdp_orders_delete(struct xrdp_orders *self)
return;
}
+ xrdp_jpeg_deinit(self->jpeg_han);
free_stream(self->out_s);
g_free(self->orders_state.text_data);
g_free(self);
@@ -200,6 +207,7 @@ xrdp_orders_check(struct xrdp_orders *self, int max_size)
}
else
{
+ xrdp_orders_init(self);
return 0;
}
}
@@ -462,7 +470,10 @@ xrdp_orders_rect(struct xrdp_orders *self, int x, int y, int cx, int cy,
char *present_ptr;
char *order_flags_ptr;
- xrdp_orders_check(self, 23);
+ if (xrdp_orders_check(self, 23) != 0)
+ {
+ return 1;
+ }
self->order_count++;
order_flags = RDP_ORDER_STANDARD;
@@ -630,7 +641,10 @@ xrdp_orders_screen_blt(struct xrdp_orders *self, int x, int y,
char *present_ptr = (char *)NULL;
char *order_flags_ptr = (char *)NULL;
- xrdp_orders_check(self, 25);
+ if (xrdp_orders_check(self, 25) != 0)
+ {
+ return 1;
+ }
self->order_count++;
order_flags = RDP_ORDER_STANDARD;
@@ -819,7 +833,10 @@ xrdp_orders_pat_blt(struct xrdp_orders *self, int x, int y,
char *order_flags_ptr;
struct xrdp_brush blank_brush;
- xrdp_orders_check(self, 39);
+ if (xrdp_orders_check(self, 39) != 0)
+ {
+ return 1;
+ }
self->order_count++;
order_flags = RDP_ORDER_STANDARD;
@@ -1033,7 +1050,10 @@ xrdp_orders_dest_blt(struct xrdp_orders *self, int x, int y,
char *present_ptr;
char *order_flags_ptr;
- xrdp_orders_check(self, 21);
+ if (xrdp_orders_check(self, 21) != 0)
+ {
+ return 1;
+ }
self->order_count++;
order_flags = RDP_ORDER_STANDARD;
@@ -1201,7 +1221,10 @@ xrdp_orders_line(struct xrdp_orders *self, int mix_mode,
rop = 0x0d; /* R2_COPYPEN */
}
- xrdp_orders_check(self, 32);
+ if (xrdp_orders_check(self, 32) != 0)
+ {
+ return 1;
+ }
self->order_count++;
order_flags = RDP_ORDER_STANDARD;
@@ -1400,7 +1423,10 @@ xrdp_orders_mem_blt(struct xrdp_orders *self, int cache_id,
char *present_ptr = (char *)NULL;
char *order_flags_ptr = (char *)NULL;
- xrdp_orders_check(self, 30);
+ if (xrdp_orders_check(self, 30) != 0)
+ {
+ return 1;
+ }
self->order_count++;
order_flags = RDP_ORDER_STANDARD;
@@ -1592,6 +1618,335 @@ xrdp_orders_mem_blt(struct xrdp_orders *self, int cache_id,
/*****************************************************************************/
/* returns error */
int APP_CC
+xrdp_orders_composite_blt(struct xrdp_orders* self, int srcidx, int srcformat,
+ int srcwidth, int srcrepeat, int* srctransform,
+ int mskflags, int mskidx, int mskformat,
+ int mskwidth, int mskrepeat, int op,
+ int srcx, int srcy, int mskx, int msky,
+ int dstx, int dsty, int width, int height,
+ int dstformat,
+ struct xrdp_rect* rect)
+{
+ int order_flags;
+ int vals[20];
+ int present;
+ char* present_ptr;
+ char* order_flags_ptr;
+
+ if (xrdp_orders_check(self, 80) != 0)
+ {
+ return 1;
+ }
+ self->order_count++;
+ order_flags = RDP_ORDER_STANDARD;
+ if (self->orders_state.last_order != RDP_ORDER_COMPOSITE)
+ {
+ order_flags |= RDP_ORDER_CHANGE;
+ }
+ self->orders_state.last_order = RDP_ORDER_COMPOSITE;
+ if (rect != 0)
+ {
+ /* if clip is present, still check if its needed */
+ if (dstx < rect->left || dsty < rect->top ||
+ dstx + width > rect->right || dsty + height > rect->bottom)
+ {
+ order_flags |= RDP_ORDER_BOUNDS;
+ if (xrdp_orders_last_bounds(self, rect))
+ {
+
+ order_flags |= RDP_ORDER_LASTBOUNDS;
+
+ }
+ }
+ }
+ vals[0] = srcx;
+ vals[1] = self->orders_state.com_blt_srcx;
+ vals[2] = srcy;
+ vals[3] = self->orders_state.com_blt_srcy;
+ vals[4] = mskx;
+ vals[5] = self->orders_state.com_blt_mskx;
+ vals[6] = msky;
+ vals[7] = self->orders_state.com_blt_msky;
+ vals[8] = dstx;
+ vals[9] = self->orders_state.com_blt_dstx;
+ vals[10] = dsty;
+ vals[11] = self->orders_state.com_blt_dsty;
+ vals[12] = width;
+ vals[13] = self->orders_state.com_blt_width;
+ vals[14] = height;
+ vals[15] = self->orders_state.com_blt_height;
+ vals[16] = srcwidth;
+ vals[17] = self->orders_state.com_blt_srcwidth;
+ vals[18] = mskwidth;
+ vals[19] = self->orders_state.com_blt_mskwidth;
+ if (xrdp_orders_send_delta(self, vals, 20))
+ {
+ order_flags |= RDP_ORDER_DELTA;
+ }
+ /* order_flags, set later, 1 byte */
+ order_flags_ptr = self->out_s->p;
+ out_uint8s(self->out_s, 1);
+ if (order_flags & RDP_ORDER_CHANGE)
+ {
+ out_uint8(self->out_s, self->orders_state.last_order);
+ }
+ present = 0;
+ /* present, set later, 3 bytes */
+ present_ptr = self->out_s->p;
+ out_uint8s(self->out_s, 3);
+ if ((order_flags & RDP_ORDER_BOUNDS) &&
+ !(order_flags & RDP_ORDER_LASTBOUNDS))
+ {
+ xrdp_orders_out_bounds(self, rect);
+ }
+
+ if (srcidx != self->orders_state.com_blt_srcidx)
+ {
+ present |= 0x000001;
+ out_uint16_le(self->out_s, srcidx);
+ self->orders_state.com_blt_srcidx = srcidx;
+ }
+
+ if (srcformat != self->orders_state.com_blt_srcformat)
+ {
+ present |= 0x000002;
+ out_uint32_le(self->out_s, srcformat);
+ self->orders_state.com_blt_srcformat = srcformat;
+ }
+
+ if (srcwidth != self->orders_state.com_blt_srcwidth)
+ {
+ present |= 0x000004;
+ if (order_flags & RDP_ORDER_DELTA)
+ {
+ out_uint8(self->out_s, srcwidth - self->orders_state.com_blt_srcwidth);
+ }
+ else
+ {
+ out_uint16_le(self->out_s, srcwidth);
+ }
+ self->orders_state.com_blt_srcwidth = srcwidth;
+ }
+
+ if (srcrepeat != self->orders_state.com_blt_srcrepeat)
+ {
+ present |= 0x000008;
+ out_uint8(self->out_s, srcrepeat);
+ self->orders_state.com_blt_srcrepeat = srcrepeat;
+ }
+
+ if (srctransform != 0)
+ {
+ if (srctransform[0] != self->orders_state.com_blt_srctransform[0])
+ {
+ present |= 0x000010;
+ out_uint32_le(self->out_s, srctransform[0]);
+ self->orders_state.com_blt_srctransform[0] = srctransform[0];
+ }
+ if (g_memcmp(&(srctransform[1]),
+ &(self->orders_state.com_blt_srctransform[1]),
+ 36) != 0)
+ {
+ present |= 0x000020;
+ out_uint32_le(self->out_s, srctransform[1]);
+ out_uint32_le(self->out_s, srctransform[2]);
+ out_uint32_le(self->out_s, srctransform[3]);
+ out_uint32_le(self->out_s, srctransform[4]);
+ out_uint32_le(self->out_s, srctransform[5]);
+ out_uint32_le(self->out_s, srctransform[6]);
+ out_uint32_le(self->out_s, srctransform[7]);
+ out_uint32_le(self->out_s, srctransform[8]);
+ out_uint32_le(self->out_s, srctransform[9]);
+ }
+ }
+ else
+ {
+ if (self->orders_state.com_blt_srctransform[0] != 0)
+ {
+ present |= 0x000010;
+ out_uint32_le(self->out_s, 0);
+ self->orders_state.com_blt_srctransform[0] = 0;
+ }
+ }
+
+ if (mskflags != self->orders_state.com_blt_mskflags)
+ {
+ present |= 0x000040;
+ out_uint8(self->out_s, mskflags);
+ self->orders_state.com_blt_mskflags = mskflags;
+ }
+
+ if (mskidx != self->orders_state.com_blt_mskidx)
+ {
+ present |= 0x000080;
+ out_uint16_le(self->out_s, mskidx);
+ self->orders_state.com_blt_mskidx = mskidx;
+ }
+
+ if (mskformat != self->orders_state.com_blt_mskformat)
+ {
+ present |= 0x000100;
+ out_uint32_le(self->out_s, mskformat);
+ self->orders_state.com_blt_mskformat = mskformat;
+ }
+
+ if (mskwidth != self->orders_state.com_blt_mskwidth)
+ {
+ present |= 0x000200;
+ if (order_flags & RDP_ORDER_DELTA)
+ {
+ out_uint8(self->out_s, mskwidth - self->orders_state.com_blt_mskwidth);
+ }
+ else
+ {
+ out_uint16_le(self->out_s, mskwidth);
+ }
+ self->orders_state.com_blt_mskwidth = mskwidth;
+ }
+
+ if (mskrepeat != self->orders_state.com_blt_mskrepeat)
+ {
+ present |= 0x000400;
+ out_uint8(self->out_s, mskrepeat);
+ self->orders_state.com_blt_mskrepeat = mskrepeat;
+ }
+
+ if (op != self->orders_state.com_blt_op)
+ {
+ present |= 0x000800;
+ out_uint8(self->out_s, op);
+ self->orders_state.com_blt_op = op;
+ }
+
+ if (srcx != self->orders_state.com_blt_srcx)
+ {
+ present |= 0x001000;
+ if (order_flags & RDP_ORDER_DELTA)
+ {
+ out_uint8(self->out_s, srcx - self->orders_state.com_blt_srcx);
+ }
+ else
+ {
+ out_uint16_le(self->out_s, srcx);
+ }
+ self->orders_state.com_blt_srcx = srcx;
+ }
+
+ if (srcy != self->orders_state.com_blt_srcy)
+ {
+ present |= 0x002000;
+ if (order_flags & RDP_ORDER_DELTA)
+ {
+ out_uint8(self->out_s, srcy - self->orders_state.com_blt_srcy);
+ }
+ else
+ {
+ out_uint16_le(self->out_s, srcy);
+ }
+ self->orders_state.com_blt_srcy = srcy;
+ }
+
+ if (mskx != self->orders_state.com_blt_mskx)
+ {
+ present |= 0x004000;
+ if (order_flags & RDP_ORDER_DELTA)
+ {
+ out_uint8(self->out_s, mskx - self->orders_state.com_blt_mskx);
+ }
+ else
+ {
+ out_uint16_le(self->out_s, mskx);
+ }
+ self->orders_state.com_blt_mskx = mskx;
+ }
+
+ if (msky != self->orders_state.com_blt_msky)
+ {
+ present |= 0x008000;
+ if (order_flags & RDP_ORDER_DELTA)
+ {
+ out_uint8(self->out_s, msky - self->orders_state.com_blt_msky);
+ }
+ else
+ {
+ out_uint16_le(self->out_s, msky);
+ }
+ self->orders_state.com_blt_msky = msky;
+ }
+
+ if (dstx != self->orders_state.com_blt_dstx)
+ {
+ present |= 0x010000;
+ if (order_flags & RDP_ORDER_DELTA)
+ {
+ out_uint8(self->out_s, dstx - self->orders_state.com_blt_dstx);
+ }
+ else
+ {
+ out_uint16_le(self->out_s, dstx);
+ }
+ self->orders_state.com_blt_dstx = dstx;
+ }
+
+ if (dsty != self->orders_state.com_blt_dsty)
+ {
+ present |= 0x020000;
+ if (order_flags & RDP_ORDER_DELTA)
+ {
+ out_uint8(self->out_s, dsty - self->orders_state.com_blt_dsty);
+ }
+ else
+ {
+ out_uint16_le(self->out_s, dsty);
+ }
+ self->orders_state.com_blt_dsty = dsty;
+ }
+
+ if (width != self->orders_state.com_blt_width)
+ {
+ present |= 0x040000;
+ if (order_flags & RDP_ORDER_DELTA)
+ {
+ out_uint8(self->out_s, width - self->orders_state.com_blt_width);
+ }
+ else
+ {
+ out_uint16_le(self->out_s, width);
+ }
+ self->orders_state.com_blt_width = width;
+ }
+
+ if (height != self->orders_state.com_blt_height)
+ {
+ present |= 0x080000;
+ if (order_flags & RDP_ORDER_DELTA)
+ {
+ out_uint8(self->out_s, height - self->orders_state.com_blt_height);
+ }
+ else
+ {
+ out_uint16_le(self->out_s, height);
+ }
+ self->orders_state.com_blt_height = height;
+ }
+
+ if (dstformat != self->orders_state.com_blt_dstformat)
+ {
+ present |= 0x100000;
+ out_uint32_le(self->out_s, dstformat);
+ self->orders_state.com_blt_dstformat = dstformat;
+ }
+
+ xrdp_order_pack_small_or_tiny(self, order_flags_ptr, order_flags,
+
+ present_ptr, present, 3);
+
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns error */
+int APP_CC
xrdp_orders_text(struct xrdp_orders *self,
int font, int flags, int mixmode,
int fg_color, int bg_color,
@@ -1607,8 +1962,10 @@ xrdp_orders_text(struct xrdp_orders *self,
char *present_ptr = (char *)NULL;
char *order_flags_ptr = (char *)NULL;
- //xrdp_orders_check(self, 100);
- xrdp_orders_check(self, 44+data_len);
+ if (xrdp_orders_check(self, 44 + data_len) != 0)
+ {
+ return 1;
+ }
self->order_count++;
order_flags = RDP_ORDER_STANDARD;
@@ -1794,7 +2151,10 @@ xrdp_orders_send_palette(struct xrdp_orders *self, int *palette,
int len;
int i;
- xrdp_orders_check(self, 2000);
+ if (xrdp_orders_check(self, 2000) != 0)
+ {
+ return 1;
+ }
self->order_count++;
order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
out_uint8(self->out_s, order_flags);
@@ -1854,7 +2214,10 @@ xrdp_orders_send_raw_bitmap(struct xrdp_orders *self,
Bpp = (bpp + 7) / 8;
bufsize = (width + e) * height * Bpp;
- xrdp_orders_check(self, bufsize + 16);
+ if (xrdp_orders_check(self, bufsize + 16) != 0)
+ {
+ return 1;
+ }
self->order_count++;
order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
out_uint8(self->out_s, order_flags);
@@ -1961,7 +2324,10 @@ height(%d)", lines_sending, height);
bufsize = (int)(s->p - p);
Bpp = (bpp + 7) / 8;
- xrdp_orders_check(self, bufsize + 16);
+ if (xrdp_orders_check(self, bufsize + 16) != 0)
+ {
+ return 1;
+ }
self->order_count++;
order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
out_uint8(self->out_s, order_flags);
@@ -2015,15 +2381,28 @@ xrdp_orders_send_font(struct xrdp_orders *self,
int order_flags = 0;
int datasize = 0;
int len = 0;
+ int flags;
- datasize = FONT_DATASIZE(font_char);
- xrdp_orders_check(self, datasize + 18);
+ if (font_char->bpp == 8) /* alpha font */
+ {
+ datasize = ((font_char->width + 3) & ~3) * font_char->height;
+ flags = 8 | 0x4000;
+ }
+ else
+ {
+ datasize = FONT_DATASIZE(font_char);
+ flags = 8;
+ }
+ if (xrdp_orders_check(self, datasize + 18) != 0)
+ {
+ return 1;
+ }
self->order_count++;
order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
out_uint8(self->out_s, order_flags);
len = (datasize + 12) - 7; /* length after type minus 7 */
out_uint16_le(self->out_s, len);
- out_uint16_le(self->out_s, 8); /* flags */
+ out_uint16_le(self->out_s, flags);
out_uint8(self->out_s, RDP_ORDER_FONTCACHE); /* type */
out_uint8(self->out_s, font_index);
out_uint8(self->out_s, 1); /* num of chars */
@@ -2074,7 +2453,10 @@ xrdp_orders_send_raw_bitmap2(struct xrdp_orders *self,
Bpp = (bpp + 7) / 8;
bufsize = (width + e) * height * Bpp;
- xrdp_orders_check(self, bufsize + 14);
+ if (xrdp_orders_check(self, bufsize + 14) != 0)
+ {
+ return 1;
+ }
self->order_count++;
order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
out_uint8(self->out_s, order_flags);
@@ -2091,6 +2473,25 @@ xrdp_orders_send_raw_bitmap2(struct xrdp_orders *self,
i = cache_idx & 0xff;
out_uint8(self->out_s, i);
+ if (1 && Bpp == 3)
+ {
+ for (i = height - 1; i >= 0; i--)
+ {
+ 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);
+ }
+ for (j = 0; j < e; j++)
+ {
+ out_uint8s(self->out_s, Bpp);
+ }
+ }
+ }
+ else
+ {
for (i = height - 1; i >= 0; i--)
{
for (j = 0; j < width; j++)
@@ -2120,6 +2521,7 @@ xrdp_orders_send_raw_bitmap2(struct xrdp_orders *self,
out_uint8s(self->out_s, Bpp);
}
}
+ }
return 0;
}
@@ -2182,7 +2584,10 @@ height(%d)", lines_sending, height);
bufsize = (int)(s->p - p);
Bpp = (bpp + 7) / 8;
- xrdp_orders_check(self, bufsize + 14);
+ if (xrdp_orders_check(self, bufsize + 14) != 0)
+ {
+ return 1;
+ }
self->order_count++;
order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
out_uint8(self->out_s, order_flags);
@@ -2228,7 +2633,7 @@ xrdp_orders_send_as_jpeg(struct xrdp_orders *self,
return 1;
}
-#if defined(XRDP_FREERDP1)
+#if defined(XRDP_NEUTRINORDP)
/*****************************************************************************/
/* secondary drawing order (bitmap v3) using remotefx compression */
static int APP_CC
@@ -2246,7 +2651,9 @@ xrdp_orders_send_as_rfx(struct xrdp_orders *self,
return 0;
}
- if (width * height < 64)
+ LLOGLN(10, ("width %d height %d rfx_min_pixel %d", width, height,
+ self->rfx_min_pixel));
+ if (width * height < self->rfx_min_pixel)
{
return 0;
}
@@ -2267,7 +2674,10 @@ xrdp_orders_out_v3(struct xrdp_orders *self, int cache_id, int cache_idx,
int i;
Bpp = (bpp + 7) / 8;
- xrdp_orders_check(self, bufsize + 30);
+ if (xrdp_orders_check(self, bufsize + 30) != 0)
+ {
+ return 1;
+ }
self->order_count++;
order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
out_uint8(self->out_s, order_flags);
@@ -2306,7 +2716,7 @@ xrdp_orders_send_bitmap3(struct xrdp_orders *self,
struct stream *xr_s; /* xrdp stream */
struct stream *temp_s; /* xrdp stream */
struct xrdp_client_info *ci;
-#if defined(XRDP_FREERDP1)
+#if defined(XRDP_NEUTRINORDP)
STREAM *fr_s; /* FreeRDP stream */
RFX_CONTEXT *context;
RFX_RECT rect;
@@ -2321,7 +2731,7 @@ xrdp_orders_send_bitmap3(struct xrdp_orders *self,
if (ci->v3_codec_id == ci->rfx_codec_id)
{
-#if defined(XRDP_FREERDP1)
+#if defined(XRDP_NEUTRINORDP)
if (!xrdp_orders_send_as_rfx(self, width, height, bpp, hints))
{
@@ -2374,7 +2784,7 @@ xrdp_orders_send_bitmap3(struct xrdp_orders *self,
make_stream(temp_s);
init_stream(temp_s, 16384);
quality = ci->jpeg_prop[0];
- xrdp_jpeg_compress(data, width, height, xr_s, bpp, 16384,
+ xrdp_jpeg_compress(self->jpeg_han, data, width, height, xr_s, bpp, 16384,
height - 1, temp_s, e, quality);
s_mark_end(xr_s);
bufsize = (int)(xr_s->end - xr_s->data);
@@ -2406,7 +2816,10 @@ xrdp_orders_send_brush(struct xrdp_orders *self, int width, int height,
int order_flags = 0;
int len = 0;
- xrdp_orders_check(self, size + 12);
+ if (xrdp_orders_check(self, size + 12) != 0)
+ {
+ return 1;
+ }
self->order_count++;
order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
out_uint8(self->out_s, order_flags);
@@ -2448,7 +2861,10 @@ xrdp_orders_send_create_os_surface(struct xrdp_orders *self, int id,
bytes += num_del_list * 2;
}
- xrdp_orders_check(self, bytes);
+ if (xrdp_orders_check(self, bytes) != 0)
+ {
+ return 1;
+ }
self->order_count++;
order_flags = RDP_ORDER_SECONDARY;
order_flags |= 1 << 2; /* type RDP_ORDER_ALTSEC_CREATE_OFFSCR_BITMAP */
@@ -2489,7 +2905,10 @@ xrdp_orders_send_switch_os_surface(struct xrdp_orders *self, int id)
int order_flags;
int cache_id;
- xrdp_orders_check(self, 3);
+ if (xrdp_orders_check(self, 3) != 0)
+ {
+ return 1;
+ }
self->order_count++;
order_flags = RDP_ORDER_SECONDARY;
order_flags |= 0 << 2; /* type RDP_ORDER_ALTSEC_SWITCH_SURFACE */
diff --git a/libxrdp/xrdp_orders_rail.c b/libxrdp/xrdp_orders_rail.c
index bd91b543..91d4b607 100644
--- a/libxrdp/xrdp_orders_rail.c
+++ b/libxrdp/xrdp_orders_rail.c
@@ -34,7 +34,10 @@ xrdp_orders_send_window_delete(struct xrdp_orders *self, int window_id)
int field_present_flags;
order_size = 11;
- xrdp_orders_check(self, order_size);
+ if (xrdp_orders_check(self, order_size) != 0)
+ {
+ return 1;
+ }
self->order_count++;
order_flags = RDP_ORDER_SECONDARY;
order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
@@ -64,7 +67,10 @@ xrdp_orders_send_window_cached_icon(struct xrdp_orders *self,
int field_present_flags;
order_size = 14;
- xrdp_orders_check(self, order_size);
+ if (xrdp_orders_check(self, order_size) != 0)
+ {
+ return 1;
+ }
self->order_count++;
order_flags = RDP_ORDER_SECONDARY;
order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
@@ -155,7 +161,10 @@ xrdp_orders_send_window_icon(struct xrdp_orders *self,
order_size += icon_info->cmap_bytes + 2;
}
- xrdp_orders_check(self, order_size);
+ if (xrdp_orders_check(self, order_size) != 0)
+ {
+ return 1;
+ }
self->order_count++;
order_flags = RDP_ORDER_SECONDARY;
order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
@@ -324,7 +333,10 @@ xrdp_orders_send_window_new_update(struct xrdp_orders *self, int window_id,
order_size += 8 * window_state->num_visibility_rects;
}
- xrdp_orders_check(self, order_size);
+ if (xrdp_orders_check(self, order_size) != 0)
+ {
+ return 1;
+ }
self->order_count++;
order_flags = RDP_ORDER_SECONDARY;
order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
@@ -465,7 +477,10 @@ xrdp_orders_send_notify_delete(struct xrdp_orders *self, int window_id,
int field_present_flags;
order_size = 15;
- xrdp_orders_check(self, order_size);
+ if (xrdp_orders_check(self, order_size) != 0)
+ {
+ return 1;
+ }
self->order_count++;
order_flags = RDP_ORDER_SECONDARY;
order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
@@ -560,7 +575,10 @@ xrdp_orders_send_notify_new_update(struct xrdp_orders *self,
order_size += 3;
}
- xrdp_orders_check(self, order_size);
+ if (xrdp_orders_check(self, order_size) != 0)
+ {
+ return 1;
+ }
self->order_count++;
order_flags = RDP_ORDER_SECONDARY;
order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
@@ -651,7 +669,10 @@ xrdp_orders_send_monitored_desktop(struct xrdp_orders *self,
order_size += mdo->num_window_ids * 4;
}
- xrdp_orders_check(self, order_size);
+ if (xrdp_orders_check(self, order_size) != 0)
+ {
+ return 1;
+ }
self->order_count++;
order_flags = RDP_ORDER_SECONDARY;
order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c
index 93219968..9147287e 100644
--- a/libxrdp/xrdp_rdp.c
+++ b/libxrdp/xrdp_rdp.c
@@ -21,7 +21,7 @@
#include "libxrdp.h"
#include "log.h"
-#if defined(XRDP_FREERDP1)
+#if defined(XRDP_NEUTRINORDP)
#include <freerdp/codec/rfx.h>
#endif
@@ -88,15 +88,15 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info)
if (g_strcasecmp(item, "bitmap_cache") == 0)
{
- client_info->use_bitmap_cache = text2bool(value);
+ client_info->use_bitmap_cache = g_text2bool(value);
}
else if (g_strcasecmp(item, "bitmap_compression") == 0)
{
- client_info->use_bitmap_comp = text2bool(value);
+ client_info->use_bitmap_comp = g_text2bool(value);
}
else if (g_strcasecmp(item, "bulk_compression") == 0)
{
- client_info->use_bulk_comp = text2bool(value);
+ client_info->use_bulk_comp = g_text2bool(value);
}
else if (g_strcasecmp(item, "crypt_level") == 0)
{
@@ -121,23 +121,35 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info)
}
else if (g_strcasecmp(item, "allow_channels") == 0)
{
- client_info->channel_code = text2bool(value);
+ client_info->channel_code = g_text2bool(value);
if (client_info->channel_code == 0)
{
log_message(LOG_LEVEL_DEBUG,"Info - All channels are disabled");
}
}
+ else if (g_strcasecmp(item, "allow_multimon") == 0)
+ {
+ client_info->multimon = g_text2bool(value);
+ if (client_info->multimon == 0)
+ {
+ log_message(LOG_LEVEL_DEBUG,"Info - Multi monitor server support disabled");
+ }
+ }
else if (g_strcasecmp(item, "max_bpp") == 0)
{
client_info->max_bpp = g_atoi(value);
}
+ else if (g_strcasecmp(item, "rfx_min_pixel") == 0)
+ {
+ client_info->rfx_min_pixel = g_atoi(value);
+ }
else if (g_strcasecmp(item, "new_cursors") == 0)
{
- client_info->pointer_flags = text2bool(value) == 0 ? 2 : 0;
+ client_info->pointer_flags = g_text2bool(value) == 0 ? 2 : 0;
}
else if (g_strcasecmp(item, "require_credentials") == 0)
{
- client_info->require_credentials = text2bool(value);
+ client_info->require_credentials = g_text2bool(value);
}
}
@@ -146,7 +158,7 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info)
return 0;
}
-#if defined(XRDP_FREERDP1)
+#if defined(XRDP_NEUTRINORDP)
/*****************************************************************************/
static void
cpuid(tui32 info, tui32 *eax, tui32 *ebx, tui32 *ecx, tui32 *edx)
@@ -215,7 +227,7 @@ xrdp_rdp_create(struct xrdp_session *session, struct trans *trans)
xrdp_rdp_read_config(&self->client_info);
/* create sec layer */
self->sec_layer = xrdp_sec_create(self, trans, self->client_info.crypt_level,
- self->client_info.channel_code);
+ self->client_info.channel_code, self->client_info.multimon);
/* default 8 bit v1 color bitmap cache entries and size */
self->client_info.cache1_entries = 600;
self->client_info.cache1_size = 256;
@@ -227,7 +239,7 @@ xrdp_rdp_create(struct xrdp_session *session, struct trans *trans)
bytes = sizeof(self->client_info.client_ip) - 1;
g_write_ip_address(trans->sck, self->client_info.client_ip, bytes);
self->mppc_enc = mppc_enc_new(PROTO_RDP_50);
-#if defined(XRDP_FREERDP1)
+#if defined(XRDP_NEUTRINORDP)
self->rfx_enc = rfx_context_new();
rfx_context_set_cpu_opt(self->rfx_enc, xrdp_rdp_detect_cpu());
#endif
@@ -247,7 +259,7 @@ xrdp_rdp_delete(struct xrdp_rdp *self)
xrdp_sec_delete(self->sec_layer);
mppc_enc_free(self->mppc_enc);
-#if defined(XRDP_FREERDP1)
+#if defined(XRDP_NEUTRINORDP)
rfx_context_free((RFX_CONTEXT *)(self->rfx_enc));
#endif
g_free(self);
@@ -421,29 +433,26 @@ xrdp_rdp_send_data(struct xrdp_rdp *self, struct stream *s,
"tocomplen %d", mppc_enc->flags, mppc_enc->bytes_in_opb,
mppc_enc->historyOffset, tocomplen));
- if (mppc_enc->flags & RDP_MPPC_COMPRESSED)
- {
- clen = mppc_enc->bytes_in_opb + 18;
- pdulen = clen;
- ctype = mppc_enc->flags;
- iso_offset = (int)(s->iso_hdr - s->data);
- mcs_offset = (int)(s->mcs_hdr - s->data);
- sec_offset = (int)(s->sec_hdr - s->data);
- rdp_offset = (int)(s->rdp_hdr - s->data);
-
- /* outputBuffer has 64 bytes preceding it */
- ls.data = mppc_enc->outputBuffer - (rdp_offset + 18);
- ls.p = ls.data + rdp_offset;
- ls.end = ls.p + clen;
- ls.size = clen;
- ls.iso_hdr = ls.data + iso_offset;
- ls.mcs_hdr = ls.data + mcs_offset;
- ls.sec_hdr = ls.data + sec_offset;
- ls.rdp_hdr = ls.data + rdp_offset;
- ls.channel_hdr = 0;
- ls.next_packet = 0;
- s = &ls;
- }
+ clen = mppc_enc->bytes_in_opb + 18;
+ pdulen = clen;
+ ctype = mppc_enc->flags;
+ iso_offset = (int)(s->iso_hdr - s->data);
+ mcs_offset = (int)(s->mcs_hdr - s->data);
+ sec_offset = (int)(s->sec_hdr - s->data);
+ rdp_offset = (int)(s->rdp_hdr - s->data);
+
+ /* outputBuffer has 64 bytes preceding it */
+ ls.data = mppc_enc->outputBuffer - (rdp_offset + 18);
+ ls.p = ls.data + rdp_offset;
+ ls.end = ls.p + clen;
+ ls.size = clen;
+ ls.iso_hdr = ls.data + iso_offset;
+ ls.mcs_hdr = ls.data + mcs_offset;
+ ls.sec_hdr = ls.data + sec_offset;
+ ls.rdp_hdr = ls.data + rdp_offset;
+ ls.channel_hdr = 0;
+ ls.next_packet = 0;
+ s = &ls;
}
else
{
@@ -514,6 +523,11 @@ xrdp_rdp_parse_client_mcs_data(struct xrdp_rdp *self)
p = &(self->sec_layer->client_mcs_data);
p->p = p->data;
+ if (!s_check_rem(p, 31 + 2 + 2 + 120 + 2))
+ {
+ g_writeln("xrdp_rdp_parse_client_mcs_data: error");
+ return 1;
+ }
in_uint8s(p, 31);
in_uint16_le(p, self->client_info.width);
in_uint16_le(p, self->client_info.height);
@@ -524,6 +538,10 @@ xrdp_rdp_parse_client_mcs_data(struct xrdp_rdp *self)
switch (i)
{
case 0xca01:
+ if (!s_check_rem(p, 6 + 1))
+ {
+ return 1;
+ }
in_uint8s(p, 6);
in_uint8(p, i);
@@ -574,6 +592,14 @@ xrdp_rdp_incoming(struct xrdp_rdp *self)
MCS_USERCHANNEL_BASE;
xrdp_rdp_parse_client_mcs_data(self);
DEBUG(("out xrdp_rdp_incoming mcs channel %d", self->mcs_channel));
+
+ g_strncpy(self->client_info.client_addr,
+ self->sec_layer->mcs_layer->iso_layer->tcp_layer->trans->addr,
+ sizeof(self->client_info.client_addr) - 1);
+ g_strncpy(self->client_info.client_port,
+ self->sec_layer->mcs_layer->iso_layer->tcp_layer->trans->port,
+ sizeof(self->client_info.client_port) - 1);
+
return 0;
}
@@ -586,6 +612,7 @@ xrdp_rdp_send_demand_active(struct xrdp_rdp *self)
int caps_size;
int codec_caps_count;
int codec_caps_size;
+ int flags;
char *caps_count_ptr;
char *caps_size_ptr;
char *caps_ptr;
@@ -679,38 +706,38 @@ xrdp_rdp_send_demand_active(struct xrdp_rdp *self)
out_uint16_le(s, 0x2f); /* Number of fonts */
out_uint16_le(s, 0x22); /* Capability flags */
/* caps */
- out_uint8(s, 1); /* dest blt */
- out_uint8(s, 1); /* pat blt */
- out_uint8(s, 1); /* screen blt */
- out_uint8(s, 1); /* mem blt */
- out_uint8(s, 0); /* tri blt */
- out_uint8(s, 0); /* unused */
- out_uint8(s, 0); /* unused */
- out_uint8(s, 0); /* nine grid */
- out_uint8(s, 1); /* line to */
- out_uint8(s, 0); /* multi nine grid */
- out_uint8(s, 1); /* rect */
- out_uint8(s, 0); /* desk save */
- out_uint8(s, 0); /* unused */
- out_uint8(s, 0); /* unused */
- out_uint8(s, 0); /* unused */
- out_uint8(s, 0); /* multi dest blt */
- out_uint8(s, 0); /* multi pat blt */
- out_uint8(s, 0); /* multi screen blt */
- out_uint8(s, 1); /* multi rect */
- out_uint8(s, 0); /* fast index */
- out_uint8(s, 0); /* polygonSC ([MS-RDPEGDI], 2.2.2.2.1.1.2.16) */
- out_uint8(s, 0); /* polygonCB ([MS-RDPEGDI], 2.2.2.2.1.1.2.17) */
- out_uint8(s, 0); /* polyline */
- out_uint8(s, 0); /* unused */
- out_uint8(s, 0); /* fast glyph */
- out_uint8(s, 0); /* ellipse */
- out_uint8(s, 0); /* ellipse */
- out_uint8(s, 0); /* ? */
- out_uint8(s, 0); /* unused */
- out_uint8(s, 0); /* unused */
- out_uint8(s, 0); /* unused */
- out_uint8(s, 0); /* unused */
+ out_uint8(s, 1); /* NEG_DSTBLT_INDEX 0x00 0 */
+ out_uint8(s, 1); /* NEG_PATBLT_INDEX 0x01 1 */
+ out_uint8(s, 1); /* NEG_SCRBLT_INDEX 0x02 2 */
+ out_uint8(s, 1); /* NEG_MEMBLT_INDEX 0x03 3 */
+ out_uint8(s, 0); /* NEG_MEM3BLT_INDEX 0x04 4 */
+ out_uint8(s, 0); /* NEG_ATEXTOUT_INDEX 0x05 5 */
+ out_uint8(s, 0); /* NEG_AEXTTEXTOUT_INDEX 0x06 6 */
+ out_uint8(s, 0); /* NEG_DRAWNINEGRID_INDEX 0x07 7 */
+ out_uint8(s, 1); /* NEG_LINETO_INDEX 0x08 8 */
+ out_uint8(s, 0); /* NEG_MULTI_DRAWNINEGRID_INDEX 0x09 9 */
+ out_uint8(s, 1); /* NEG_OPAQUE_RECT_INDEX 0x0A 10 */
+ out_uint8(s, 0); /* NEG_SAVEBITMAP_INDEX 0x0B 11 */
+ out_uint8(s, 0); /* NEG_WTEXTOUT_INDEX 0x0C 12 */
+ out_uint8(s, 0); /* NEG_MEMBLT_V2_INDEX 0x0D 13 */
+ out_uint8(s, 0); /* NEG_MEM3BLT_V2_INDEX 0x0E 14 */
+ out_uint8(s, 0); /* NEG_MULTIDSTBLT_INDEX 0x0F 15 */
+ out_uint8(s, 0); /* NEG_MULTIPATBLT_INDEX 0x10 16 */
+ out_uint8(s, 0); /* NEG_MULTISCRBLT_INDEX 0x11 17 */
+ out_uint8(s, 1); /* NEG_MULTIOPAQUERECT_INDEX 0x12 18 */
+ out_uint8(s, 0); /* NEG_FAST_INDEX_INDEX 0x13 19 */
+ out_uint8(s, 0); /* NEG_POLYGON_SC_INDEX 0x14 20 */
+ out_uint8(s, 0); /* NEG_POLYGON_CB_INDEX 0x15 21 */
+ out_uint8(s, 0); /* NEG_POLYLINE_INDEX 0x16 22 */
+ out_uint8(s, 0); /* unused 0x17 23 */
+ out_uint8(s, 0); /* NEG_FAST_GLYPH_INDEX 0x18 24 */
+ out_uint8(s, 0); /* NEG_ELLIPSE_SC_INDEX 0x19 25 */
+ out_uint8(s, 0); /* NEG_ELLIPSE_CB_INDEX 0x1A 26 */
+ out_uint8(s, 1); /* NEG_GLYPH_INDEX_INDEX 0x1B 27 */
+ out_uint8(s, 0); /* NEG_GLYPH_WEXTTEXTOUT_INDEX 0x1C 28 */
+ out_uint8(s, 0); /* NEG_GLYPH_WLONGTEXTOUT_INDEX 0x1D 29 */
+ out_uint8(s, 0); /* NEG_GLYPH_WLONGEXTTEXTOUT_INDEX 0x1E 30 */
+ out_uint8(s, 0); /* unused 0x1F 31 */
out_uint16_le(s, 0x6a1);
/* declare support of bitmap cache rev3 */
out_uint16_le(s, XR_ORDERFLAGS_EX_CACHE_BITMAP_REV3_SUPPORT);
@@ -773,18 +800,16 @@ xrdp_rdp_send_demand_active(struct xrdp_rdp *self)
caps_count++;
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;
if (self->client_info.use_fast_path & 2)
- {
- /* INPUT_FLAG_SCANCODES 0x0001
- INPUT_FLAG_FASTPATH_INPUT 0x0008
- INPUT_FLAG_FASTPATH_INPUT2 0x0020 */
- out_uint8(s, 1 | 8 | 0x20);
- }
- else
- {
- out_uint8(s, 1);
- }
- out_uint8s(s, 83);
+ flags |= 0x0008 | 0x0020;
+ out_uint16_le(s, flags);
+ out_uint8s(s, 82);
/* Remote Programs Capability Set */
caps_count++;
@@ -837,6 +862,11 @@ xrdp_process_capset_general(struct xrdp_rdp *self, struct stream *s,
{
int i;
+ if (len < 10 + 2)
+ {
+ g_writeln("xrdp_process_capset_general: error");
+ return 1;
+ }
in_uint8s(s, 10);
in_uint16_le(s, i);
/* use_compact_packets is pretty much 'use rdp5' */
@@ -858,6 +888,11 @@ xrdp_process_capset_order(struct xrdp_rdp *self, struct stream *s,
int cap_flags;
DEBUG(("order capabilities"));
+ if (len < 20 + 2 + 2 + 2 + 2 + 2 + 2 + 32 + 2 + 2 + 4 + 4 + 4 + 4)
+ {
+ g_writeln("xrdp_process_capset_order: error");
+ return 1;
+ }
in_uint8s(s, 20); /* Terminal desc, pad */
in_uint8s(s, 2); /* Cache X granularity */
in_uint8s(s, 2); /* Cache Y granularity */
@@ -915,13 +950,32 @@ static int APP_CC
xrdp_process_capset_bmpcache(struct xrdp_rdp *self, struct stream *s,
int len)
{
+ int i;
+
+ if (len < 24 + 2 + 2 + 2 + 2 + 2 + 2)
+ {
+ g_writeln("xrdp_process_capset_bmpcache: error");
+ return 1;
+ }
self->client_info.bitmap_cache_version |= 1;
in_uint8s(s, 24);
- in_uint16_le(s, self->client_info.cache1_entries);
+ /* cache 1 */
+ in_uint16_le(s, i);
+ i = MIN(i, XRDP_MAX_BITMAP_CACHE_IDX);
+ i = MAX(i, 0);
+ self->client_info.cache1_entries = i;
in_uint16_le(s, self->client_info.cache1_size);
- in_uint16_le(s, self->client_info.cache2_entries);
+ /* cache 2 */
+ in_uint16_le(s, i);
+ i = MIN(i, XRDP_MAX_BITMAP_CACHE_IDX);
+ i = MAX(i, 0);
+ self->client_info.cache2_entries = i;
in_uint16_le(s, self->client_info.cache2_size);
- in_uint16_le(s, self->client_info.cache3_entries);
+ /* caceh 3 */
+ in_uint16_le(s, i);
+ i = MIN(i, XRDP_MAX_BITMAP_CACHE_IDX);
+ i = MAX(i, 0);
+ self->client_info.cache3_entries = i;
in_uint16_le(s, self->client_info.cache3_size);
DEBUG(("cache1 entries %d size %d", self->client_info.cache1_entries,
self->client_info.cache1_size));
@@ -941,22 +995,30 @@ xrdp_process_capset_bmpcache2(struct xrdp_rdp *self, struct stream *s,
int Bpp = 0;
int i = 0;
+ if (len < 2 + 2 + 4 + 4 + 4)
+ {
+ g_writeln("xrdp_process_capset_bmpcache2: error");
+ return 1;
+ }
self->client_info.bitmap_cache_version |= 2;
Bpp = (self->client_info.bpp + 7) / 8;
in_uint16_le(s, i); /* cache flags */
self->client_info.bitmap_cache_persist_enable = i;
in_uint8s(s, 2); /* number of caches in set, 3 */
in_uint32_le(s, i);
- i = MIN(i, 2000);
+ i = MIN(i, XRDP_MAX_BITMAP_CACHE_IDX);
+ i = MAX(i, 0);
self->client_info.cache1_entries = i;
self->client_info.cache1_size = 256 * Bpp;
in_uint32_le(s, i);
- i = MIN(i, 2000);
+ i = MIN(i, XRDP_MAX_BITMAP_CACHE_IDX);
+ i = MAX(i, 0);
self->client_info.cache2_entries = i;
self->client_info.cache2_size = 1024 * Bpp;
in_uint32_le(s, i);
i = i & 0x7fffffff;
- i = MIN(i, 2000);
+ i = MIN(i, XRDP_MAX_BITMAP_CACHE_IDX);
+ i = MAX(i, 0);
self->client_info.cache3_entries = i;
self->client_info.cache3_size = 4096 * Bpp;
DEBUG(("cache1 entries %d size %d", self->client_info.cache1_entries,
@@ -975,6 +1037,11 @@ xrdp_process_capset_cache_v3_codec_id(struct xrdp_rdp *self, struct stream *s,
{
int codec_id;
+ if (len < 1)
+ {
+ g_writeln("xrdp_process_capset_cache_v3_codec_id: error");
+ return 1;
+ }
in_uint8(s, codec_id);
g_writeln("xrdp_process_capset_cache_v3_codec_id: cache_v3_codec_id %d",
codec_id);
@@ -992,6 +1059,11 @@ xrdp_process_capset_pointercache(struct xrdp_rdp *self, struct stream *s,
int colorPointerFlag;
int no_new_cursor;
+ if (len < 2 + 2 + 2)
+ {
+ g_writeln("xrdp_process_capset_pointercache: error");
+ return 1;
+ }
no_new_cursor = self->client_info.pointer_flags & 2;
in_uint16_le(s, colorPointerFlag);
self->client_info.pointer_flags = colorPointerFlag;
@@ -1028,6 +1100,11 @@ xrdp_process_capset_brushcache(struct xrdp_rdp *self, struct stream *s,
{
int code;
+ if (len < 4)
+ {
+ g_writeln("xrdp_process_capset_brushcache: error");
+ return 1;
+ }
in_uint32_le(s, code);
self->client_info.brush_cache_code = code;
return 0;
@@ -1040,12 +1117,11 @@ xrdp_process_offscreen_bmpcache(struct xrdp_rdp *self, struct stream *s,
{
int i32;
- if (len - 4 < 8)
+ if (len < 4 + 2 + 2)
{
- g_writeln("xrdp_process_offscreen_bmpcache: bad len");
+ g_writeln("xrdp_process_offscreen_bmpcache: error");
return 1;
}
-
in_uint32_le(s, i32);
self->client_info.offscreen_support_level = i32;
in_uint16_le(s, i32);
@@ -1066,12 +1142,11 @@ xrdp_process_capset_rail(struct xrdp_rdp *self, struct stream *s, int len)
{
int i32;
- if (len - 4 < 4)
+ if (len < 4)
{
- g_writeln("xrdp_process_capset_rail: bad len");
+ g_writeln("xrdp_process_capset_rail: error");
return 1;
}
-
in_uint32_le(s, i32);
self->client_info.rail_support_level = i32;
g_writeln("xrdp_process_capset_rail: rail_support_level %d",
@@ -1085,12 +1160,11 @@ xrdp_process_capset_window(struct xrdp_rdp *self, struct stream *s, int len)
{
int i32;
- if (len - 4 < 7)
+ if (len < 4 + 1 + 2)
{
- g_writeln("xrdp_process_capset_window: bad len");
+ g_writeln("xrdp_process_capset_window: error");
return 1;
}
-
in_uint32_le(s, i32);
self->client_info.wnd_support_level = i32;
in_uint8(s, i32);
@@ -1117,14 +1191,32 @@ xrdp_process_capset_codecs(struct xrdp_rdp *self, struct stream *s, int len)
char *codec_guid;
char *next_guid;
+ if (len < 1)
+ {
+ g_writeln("xrdp_process_capset_codecs: error");
+ return 1;
+ }
in_uint8(s, codec_count);
+ len--;
for (index = 0; index < codec_count; index++)
{
codec_guid = s->p;
+ if (len < 16 + 1 + 2)
+ {
+ g_writeln("xrdp_process_capset_codecs: error");
+ return 1;
+ }
in_uint8s(s, 16);
in_uint8(s, codec_id);
in_uint16_le(s, codec_properties_length);
+ len -= 16 + 1 + 2;
+ if (len < codec_properties_length)
+ {
+ g_writeln("xrdp_process_capset_codecs: error");
+ return 1;
+ }
+ len -= codec_properties_length;
next_guid = s->p + codec_properties_length;
if (g_memcmp(codec_guid, XR_CODEC_GUID_NSCODEC, 16) == 0)
@@ -1190,9 +1282,19 @@ xrdp_rdp_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
for (index = 0; index < num_caps; index++)
{
p = s->p;
+ if (!s_check_rem(s, 4))
+ {
+ g_writeln("xrdp_rdp_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))
+ {
+ g_writeln("xrdp_rdp_process_confirm_active: error len %d", len, s->end - s->p);
+ return 1;
+ }
+ len -= 4;
switch (type)
{
case RDP_CAPSET_GENERAL: /* 1 */
@@ -1278,7 +1380,7 @@ xrdp_rdp_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
break;
}
- s->p = p + len;
+ s->p = p + len + 4;
}
DEBUG(("out xrdp_rdp_process_confirm_active"));
@@ -1305,26 +1407,35 @@ xrdp_rdp_process_data_input(struct xrdp_rdp *self, struct stream *s)
int param2;
int time;
+ if (!s_check_rem(s, 4))
+ {
+ return 1;
+ }
in_uint16_le(s, num_events);
in_uint8s(s, 2); /* pad */
DEBUG(("in xrdp_rdp_process_data_input %d events", num_events));
for (index = 0; index < num_events; index++)
{
+ if (!s_check_rem(s, 12))
+ {
+ return 1;
+ }
in_uint32_le(s, time);
in_uint16_le(s, msg_type);
in_uint16_le(s, device_flags);
in_sint16_le(s, param1);
in_sint16_le(s, param2);
- DEBUG(("xrdp_rdp_process_data_input event %4.4x flags %4.4x param1 %d \
-param2 %d time %d", msg_type, device_flags, param1, param2, time));
+ DEBUG(("xrdp_rdp_process_data_input event %4.4x flags %4.4x param1 %d "
+ "param2 %d time %d", msg_type, device_flags, param1, param2, time));
if (self->session->callback != 0)
{
/* msg_type can be
RDP_INPUT_SYNCHRONIZE - 0
RDP_INPUT_SCANCODE - 4
- RDP_INPUT_MOUSE - 0x8001 */
+ RDP_INPUT_MOUSE - 0x8001
+ RDP_INPUT_MOUSEX - 0x8002 */
/* call to xrdp_wm.c : callback */
self->session->callback(self->session->id, msg_type, param1, param2,
device_flags, time);
diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c
index 726fcde4..f52a080d 100644
--- a/libxrdp/xrdp_sec.c
+++ b/libxrdp/xrdp_sec.c
@@ -138,7 +138,7 @@ hex_str_to_bin(char *in, char *out, int out_len)
/*****************************************************************************/
struct xrdp_sec *APP_CC
xrdp_sec_create(struct xrdp_rdp *owner, struct trans *trans, int crypt_level,
- int channel_code)
+ int channel_code, int multimon)
{
struct xrdp_sec *self;
@@ -168,6 +168,7 @@ xrdp_sec_create(struct xrdp_rdp *owner, struct trans *trans, int crypt_level,
}
self->channel_code = channel_code;
+ self->multimon = multimon;
if (self->decrypt_rc4_info != NULL)
{
@@ -331,12 +332,20 @@ unicode_in(struct stream *s, int uni_len, char *dst, int dst_len)
break;
}
+ if (!s_check_rem(s, 2))
+ {
+ return 1;
+ }
in_uint8(s, dst[dst_index]);
in_uint8s(s, 1);
dst_index++;
src_index += 2;
}
+ if (!s_check_rem(s, 2))
+ {
+ return 1;
+ }
in_uint8s(s, 2);
return 0;
}
@@ -359,6 +368,10 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
/* initialize (zero out) local variables */
g_memset(tmpdata, 0, sizeof(char) * 256);
+ if (!s_check_rem(s, 8))
+ {
+ return 1;
+ }
in_uint8s(s, 4);
in_uint32_le(s, flags);
DEBUG(("in xrdp_sec_process_logon_info flags $%x", flags));
@@ -398,6 +411,10 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
}
}
+ if (!s_check_rem(s, 2))
+ {
+ return 1;
+ }
in_uint16_le(s, len_domain);
if (len_domain > 511)
@@ -406,6 +423,10 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
return 1;
}
+ if (!s_check_rem(s, 2))
+ {
+ return 1;
+ }
in_uint16_le(s, len_user);
if (len_user > 511)
@@ -414,6 +435,10 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
return 1;
}
+ if (!s_check_rem(s, 2))
+ {
+ return 1;
+ }
in_uint16_le(s, len_password);
if (len_password > 511)
@@ -422,6 +447,10 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
return 1;
}
+ if (!s_check_rem(s, 2))
+ {
+ return 1;
+ }
in_uint16_le(s, len_program);
if (len_program > 511)
@@ -430,6 +459,10 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
return 1;
}
+ if (!s_check_rem(s, 2))
+ {
+ return 1;
+ }
in_uint16_le(s, len_directory);
if (len_directory > 511)
@@ -438,36 +471,76 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
return 1;
}
- unicode_in(s, len_domain, self->rdp_layer->client_info.domain, 255);
+ if (unicode_in(s, len_domain, self->rdp_layer->client_info.domain, 255) != 0)
+ {
+ return 1;
+ }
DEBUG(("domain %s", self->rdp_layer->client_info.domain));
- unicode_in(s, len_user, self->rdp_layer->client_info.username, 255);
+ if (unicode_in(s, len_user, self->rdp_layer->client_info.username, 255) != 0)
+ {
+ return 1;
+ }
DEBUG(("username %s", self->rdp_layer->client_info.username));
if (flags & RDP_LOGON_AUTO)
{
- unicode_in(s, len_password, self->rdp_layer->client_info.password, 255);
+ if (unicode_in(s, len_password, self->rdp_layer->client_info.password, 255) != 0)
+ {
+ return 1;
+ }
DEBUG(("flag RDP_LOGON_AUTO found"));
}
else
{
+ if (!s_check_rem(s, len_password + 2))
+ {
+ return 1;
+ }
in_uint8s(s, len_password + 2);
if (self->rdp_layer->client_info.require_credentials)
+ {
+ g_writeln("xrdp_sec_process_logon_info: credentials on cmd line is mandatory");
return 1; /* credentials on cmd line is mandatory */
+ }
}
- unicode_in(s, len_program, self->rdp_layer->client_info.program, 255);
+ if (unicode_in(s, len_program, self->rdp_layer->client_info.program, 255) != 0)
+ {
+ return 1;
+ }
DEBUG(("program %s", self->rdp_layer->client_info.program));
- unicode_in(s, len_directory, self->rdp_layer->client_info.directory, 255);
+ if (unicode_in(s, len_directory, self->rdp_layer->client_info.directory, 255) != 0)
+ {
+ return 1;
+ }
DEBUG(("directory %s", self->rdp_layer->client_info.directory));
if (flags & RDP_LOGON_BLOB)
{
+ if (!s_check_rem(s, 4))
+ {
+ return 1;
+ }
in_uint8s(s, 2); /* unknown */
in_uint16_le(s, len_ip);
- unicode_in(s, len_ip - 2, tmpdata, 255);
+ if (unicode_in(s, len_ip - 2, tmpdata, 255) != 0)
+ {
+ return 1;
+ }
+ if (!s_check_rem(s, 2))
+ {
+ return 1;
+ }
in_uint16_le(s, len_dll);
- unicode_in(s, len_dll - 2, tmpdata, 255);
- in_uint32_le(s, tzone); /* len of timetone */
+ if (unicode_in(s, len_dll - 2, tmpdata, 255) != 0)
+ {
+ return 1;
+ }
+ if (!s_check_rem(s, 4 + 62 + 22 + 62 + 26 + 4))
+ {
+ return 1;
+ }
+ in_uint32_le(s, tzone); /* len of timezone */
in_uint8s(s, 62); /* skip */
in_uint8s(s, 22); /* skip misc. */
in_uint8s(s, 62); /* skip */
@@ -676,17 +749,29 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan)
return 1;
}
+ if (!s_check_rem(s, 4))
+ {
+ return 1;
+ }
in_uint32_le(s, flags);
DEBUG((" in xrdp_sec_recv flags $%x", flags));
if (flags & SEC_ENCRYPT) /* 0x08 */
{
+ if (!s_check_rem(s, 8))
+ {
+ return 1;
+ }
in_uint8s(s, 8); /* signature */
xrdp_sec_decrypt(self, s->p, (int)(s->end - s->p));
}
if (flags & SEC_CLIENT_RANDOM) /* 0x01 */
{
+ if (!s_check_rem(s, 4 + 64))
+ {
+ return 1;
+ }
in_uint32_le(s, len);
in_uint8a(s, self->client_crypt_random, 64);
xrdp_sec_rsa_op(self->client_random, self->client_crypt_random,
@@ -836,23 +921,91 @@ xrdp_sec_process_mcs_data_channels(struct xrdp_sec *self, struct stream *s)
return 0;
}
+ if (!s_check_rem(s, 4))
+ {
+ return 1;
+ }
+
in_uint32_le(s, num_channels);
+ if (num_channels > 31)
+ {
+ return 1;
+ }
+
for (index = 0; index < num_channels; index++)
{
channel_item = (struct mcs_channel_item *)
g_malloc(sizeof(struct mcs_channel_item), 1);
+ if (!s_check_rem(s, 12))
+ {
+ return 1;
+ }
in_uint8a(s, channel_item->name, 8);
in_uint32_le(s, channel_item->flags);
channel_item->chanid = MCS_GLOBAL_CHANNEL + (index + 1);
- list_add_item(self->mcs_layer->channel_list, (long)channel_item);
+ list_add_item(self->mcs_layer->channel_list, (tintptr)channel_item);
DEBUG(("got channel flags %8.8x name %s", channel_item->flags,
channel_item->name));
}
return 0;
}
+/*****************************************************************************/
+/* reads the client monitors data */
+static int APP_CC
+xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s)
+{
+ int index;
+ int monitorCount;
+ int flags;
+ struct xrdp_client_info *client_info = (struct xrdp_client_info *)NULL;
+
+ client_info = &(self->rdp_layer->client_info);
+ DEBUG(("processing monitors data, allow_multimon is %d", self->multimon));
+ /* this is an option set in xrdp.ini */
+ if (self->multimon != 1) /* are multi-monitors allowed ? */
+ {
+ DEBUG(("[INFO] xrdp_sec_process_mcs_data_monitors: multimon is not "
+ "allowed, skipping"));
+ return 0;
+ }
+ in_uint32_le(s, flags); /* flags */
+ //verify flags - must be 0x0
+ if (flags != 0)
+ {
+ DEBUG(("[ERROR] xrdp_sec_process_mcs_data_monitors: flags MUST be "
+ "zero, detected: %d", flags));
+ return 1;
+ }
+ in_uint32_le(s, monitorCount);
+ //verify monitorCount - max 16
+ if (monitorCount > 16)
+ {
+ DEBUG(("[ERROR] xrdp_sec_process_mcs_data_monitors: max allowed "
+ "monitors is 16, detected: %d", monitorCount));
+ return 1;
+ }
+
+ g_writeln("monitorCount= %d", monitorCount); // for debugging only
+
+ client_info->monitorCount = monitorCount;
+
+ /* Add client_monitor_data to client_info struct, will later pass to X11rdp */
+ for (index = 0; index < monitorCount; index++)
+ {
+ in_uint32_le(s, client_info->minfo[index].left);
+ in_uint32_le(s, client_info->minfo[index].top);
+ in_uint32_le(s, client_info->minfo[index].right);
+ in_uint32_le(s, client_info->minfo[index].bottom);
+ in_uint32_le(s, client_info->minfo[index].is_primary);
+
+ g_writeln("got a monitor: left= %d, top= %d, right= %d, bottom= %d, is_primary?= %d", client_info->minfo[index].left,
+ client_info->minfo[index].top, client_info->minfo[index].right, client_info->minfo[index].bottom, client_info->minfo[index].is_primary);
+ }
+ return 0;
+}
/*****************************************************************************/
/* process client mcs data, we need some things in here to create the server
mcs data */
@@ -864,10 +1017,14 @@ xrdp_sec_process_mcs_data(struct xrdp_sec *self)
int tag = 0;
int size = 0;
- s = &self->client_mcs_data;
+ s = &(self->client_mcs_data);
/* set p to beginning */
s->p = s->data;
/* skip header */
+ if (!s_check_rem(s, 23))
+ {
+ return 1;
+ }
in_uint8s(s, 23);
while (s_check_rem(s, 4))
@@ -890,10 +1047,19 @@ xrdp_sec_process_mcs_data(struct xrdp_sec *self)
case SEC_TAG_CLI_CRYPT:
break;
case SEC_TAG_CLI_CHANNELS:
- xrdp_sec_process_mcs_data_channels(self, s);
+ if (xrdp_sec_process_mcs_data_channels(self, s) != 0)
+ {
+ return 1;
+ }
break;
case SEC_TAG_CLI_4:
break;
+ case SEC_TAG_CLI_MONITOR:
+ if (xrdp_sec_process_mcs_data_monitors(self, s) != 0)
+ {
+ return 1;
+ }
+ break;
default:
g_writeln("error unknown xrdp_sec_process_mcs_data tag %d size %d",
tag, size);
@@ -940,13 +1106,32 @@ xrdp_sec_out_mcs_data(struct xrdp_sec *self)
out_uint8(s, 0x63); /* c */
out_uint8(s, 0x44); /* D */
out_uint8(s, 0x6e); /* n */
- out_uint16_be(s, 0x80fc + (num_channels_even * 2));
+ if (self->mcs_layer->iso_layer->selectedProtocol != -1)
+ { // Check for RDPNEGDATA availability
+ out_uint16_be(s, 0x80fc + (num_channels_even * 2) + 4);
+ }
+ else
+ {
+ out_uint16_be(s, 0x80fc + (num_channels_even * 2));
+ }
out_uint16_le(s, SEC_TAG_SRV_INFO);
- out_uint16_le(s, 8); /* len */
+ if (self->mcs_layer->iso_layer->selectedProtocol != -1)
+ {
+ out_uint16_le(s, 12); /* len */
+ }
+ else
+ {
+ out_uint16_le(s, 8); /* len */
+ }
out_uint8(s, 4); /* 4 = rdp5 1 = rdp4 */
out_uint8(s, 0);
out_uint8(s, 8);
out_uint8(s, 0);
+ if (self->mcs_layer->iso_layer->selectedProtocol != -1)
+ {
+ /* clientReqeustedProtocol */
+ out_uint32_le(s, self->mcs_layer->iso_layer->selectedProtocol);
+ }
out_uint16_le(s, SEC_TAG_SRV_CHANNELS);
out_uint16_le(s, 8 + (num_channels_even * 2)); /* len */
out_uint16_le(s, MCS_GLOBAL_CHANNEL); /* 1003, 0x03eb main channel */
@@ -999,7 +1184,7 @@ xrdp_sec_out_mcs_data(struct xrdp_sec *self)
/*****************************************************************************/
/* process the mcs client data we received from the mcs layer */
-static void APP_CC
+static int APP_CC
xrdp_sec_in_mcs_data(struct xrdp_sec *self)
{
struct stream *s = (struct stream *)NULL;
@@ -1011,6 +1196,10 @@ xrdp_sec_in_mcs_data(struct xrdp_sec *self)
s = &(self->client_mcs_data);
/* get hostname, its unicode */
s->p = s->data;
+ if (!s_check_rem(s, 47))
+ {
+ return 1;
+ }
in_uint8s(s, 47);
g_memset(client_info->hostname, 0, 32);
c = 1;
@@ -1018,21 +1207,33 @@ xrdp_sec_in_mcs_data(struct xrdp_sec *self)
while (index < 16 && c != 0)
{
+ if (!s_check_rem(s, 2))
+ {
+ return 1;
+ }
in_uint8(s, c);
in_uint8s(s, 1);
client_info->hostname[index] = c;
index++;
}
-
/* get build */
s->p = s->data;
+ if (!s_check_rem(s, 43 + 4))
+ {
+ return 1;
+ }
in_uint8s(s, 43);
in_uint32_le(s, client_info->build);
/* get keylayout */
s->p = s->data;
+ if (!s_check_rem(s, 39 + 4))
+ {
+ return 1;
+ }
in_uint8s(s, 39);
in_uint32_le(s, client_info->keylayout);
s->p = s->data;
+ return 0;
}
/*****************************************************************************/
@@ -1059,7 +1260,8 @@ xrdp_sec_incoming(struct xrdp_sec *self)
if (file_by_name_read_section(key_file, "keys", items, values) != 0)
{
/* this is a show stopper */
- log_message(LOG_LEVEL_ALWAYS,"XRDP cannot read file: %s (check permissions)", key_file);
+ log_message(LOG_LEVEL_ALWAYS, "XRDP cannot read file: %s "
+ "(check permissions)", key_file);
list_delete(items);
list_delete(values);
return 1;
@@ -1105,7 +1307,10 @@ xrdp_sec_incoming(struct xrdp_sec *self)
(int)(self->server_mcs_data.end - self->server_mcs_data.data));
#endif
DEBUG((" out xrdp_sec_incoming"));
- xrdp_sec_in_mcs_data(self);
+ if (xrdp_sec_in_mcs_data(self) != 0)
+ {
+ return 1;
+ }
return 0;
}