Merge branch 'master' of github.com:neutrinolabs/xrdp

ulab-next
Laxmikant Rashinkar 11 years ago
commit 47ac4a897a

@ -1,7 +1,7 @@
/** /**
* xrdp: A Remote Desktop Protocol server. * xrdp: A Remote Desktop Protocol server.
* *
* Copyright (C) Jay Sorg 2004-2012 * Copyright (C) Jay Sorg 2004-2013
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

@ -125,6 +125,7 @@ int APP_CC g_get_errno(void);
int APP_CC g_execvp(const char* p1, char* args[]); int APP_CC g_execvp(const char* p1, char* args[]);
int APP_CC g_execlp3(const char* a1, const char* a2, const char* a3); int APP_CC g_execlp3(const char* a1, const char* a2, const char* a3);
void APP_CC g_signal_child_stop(void (*func)(int)); void APP_CC g_signal_child_stop(void (*func)(int));
void APP_CC g_signal_segfault(void (*func)(int));
void APP_CC g_signal_hang_up(void (*func)(int)); void APP_CC g_signal_hang_up(void (*func)(int));
void APP_CC g_signal_user_interrupt(void (*func)(int)); void APP_CC g_signal_user_interrupt(void (*func)(int));
void APP_CC g_signal_kill(void (*func)(int)); void APP_CC g_signal_kill(void (*func)(int));

@ -55,6 +55,9 @@ struct stream
/******************************************************************************/ /******************************************************************************/
#define s_check_rem(s, n) ((s)->p + (n) <= (s)->end) #define s_check_rem(s, n) ((s)->p + (n) <= (s)->end)
/******************************************************************************/
#define s_check_rem_out(s, n) ((s)->p + (n) <= (s)->data + (s)->size)
/******************************************************************************/ /******************************************************************************/
#define s_check_end(s) ((s)->p == (s)->end) #define s_check_end(s) ((s)->p == (s)->end)

@ -221,8 +221,12 @@ trans_force_read_s(struct trans *self, struct stream *in_s, int size)
while (size > 0) while (size > 0)
{ {
/* make sure stream has room */
if ((in_s->end + size) > (in_s->data + in_s->size))
{
return 1;
}
rcvd = g_tcp_recv(self->sck, in_s->end, size, 0); rcvd = g_tcp_recv(self->sck, in_s->end, size, 0);
if (rcvd == -1) if (rcvd == -1)
{ {
if (g_tcp_last_error_would_block(self->sck)) if (g_tcp_last_error_would_block(self->sck))

@ -559,4 +559,7 @@
#define CMDTYPE_FRAME_MARKER 0x0004 #define CMDTYPE_FRAME_MARKER 0x0004
#define CMDTYPE_STREAM_SURFACE_BITS 0x0006 #define CMDTYPE_STREAM_SURFACE_BITS 0x0006
#define XRDP_MAX_BITMAP_CACHE_ID 3
#define XRDP_MAX_BITMAP_CACHE_IDX 2000
#endif #endif

@ -72,20 +72,38 @@ xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code)
in_uint8s(s, 1); in_uint8s(s, 1);
in_uint16_be(s, len); in_uint16_be(s, len);
if (len < 4)
{
return 1;
}
if (xrdp_tcp_recv(self->tcp_layer, s, len - 4) != 0) if (xrdp_tcp_recv(self->tcp_layer, s, len - 4) != 0)
{ {
return 1; return 1;
} }
if (!s_check_rem(s, 2))
{
return 1;
}
in_uint8s(s, 1); in_uint8s(s, 1);
in_uint8(s, *code); in_uint8(s, *code);
if (*code == ISO_PDU_DT) if (*code == ISO_PDU_DT)
{ {
if (!s_check_rem(s, 1))
{
return 1;
}
in_uint8s(s, 1); in_uint8s(s, 1);
} }
else else
{ {
if (!s_check_rem(s, 5))
{
return 1;
}
in_uint8s(s, 5); in_uint8s(s, 5);
} }

@ -132,6 +132,11 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan)
return 1; return 1;
} }
if (!s_check_rem(s, 1))
{
return 1;
}
in_uint8(s, opcode); in_uint8(s, opcode);
appid = opcode >> 2; appid = opcode >> 2;
@ -145,6 +150,11 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan)
/* this is channels getting added from the client */ /* this is channels getting added from the client */
if (appid == MCS_CJRQ) if (appid == MCS_CJRQ)
{ {
if (!s_check_rem(s, 4))
{
return 1;
}
in_uint16_be(s, userid); in_uint16_be(s, userid);
in_uint16_be(s, chanid); in_uint16_be(s, chanid);
log_message(LOG_LEVEL_DEBUG,"MCS_CJRQ - channel join request received"); log_message(LOG_LEVEL_DEBUG,"MCS_CJRQ - channel join request received");
@ -176,6 +186,11 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan)
return 1; return 1;
} }
if (!s_check_rem(s, 6))
{
return 1;
}
in_uint8s(s, 2); in_uint8s(s, 2);
in_uint16_be(s, *chan); in_uint16_be(s, *chan);
in_uint8s(s, 1); in_uint8s(s, 1);
@ -183,6 +198,10 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan)
if (len & 0x80) if (len & 0x80)
{ {
if (!s_check_rem(s, 1))
{
return 1;
}
in_uint8s(s, 1); in_uint8s(s, 1);
} }
@ -202,10 +221,18 @@ xrdp_mcs_ber_parse_header(struct xrdp_mcs *self, struct stream *s,
if (tag_val > 0xff) if (tag_val > 0xff)
{ {
if (!s_check_rem(s, 2))
{
return 1;
}
in_uint16_be(s, tag); in_uint16_be(s, tag);
} }
else else
{ {
if (!s_check_rem(s, 1))
{
return 1;
}
in_uint8(s, tag); in_uint8(s, tag);
} }
@ -214,6 +241,11 @@ xrdp_mcs_ber_parse_header(struct xrdp_mcs *self, struct stream *s,
return 1; return 1;
} }
if (!s_check_rem(s, 1))
{
return 1;
}
in_uint8(s, l); in_uint8(s, l);
if (l & 0x80) if (l & 0x80)
@ -223,6 +255,10 @@ xrdp_mcs_ber_parse_header(struct xrdp_mcs *self, struct stream *s,
while (l > 0) while (l > 0)
{ {
if (!s_check_rem(s, 1))
{
return 1;
}
in_uint8(s, i); in_uint8(s, i);
*len = (*len << 8) | i; *len = (*len << 8) | i;
l--; l--;
@ -255,6 +291,11 @@ xrdp_mcs_parse_domain_params(struct xrdp_mcs *self, struct stream *s)
return 1; return 1;
} }
if ((len < 0) || !s_check_rem(s, len))
{
return 1;
}
in_uint8s(s, len); in_uint8s(s, len);
if (s_check(s)) if (s_check(s))
@ -276,7 +317,7 @@ xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self)
struct stream *s; struct stream *s;
make_stream(s); make_stream(s);
init_stream(s, 8192); init_stream(s, 16 * 1024);
if (xrdp_iso_recv(self->iso_layer, s) != 0) if (xrdp_iso_recv(self->iso_layer, s) != 0)
{ {
@ -296,6 +337,12 @@ xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self)
return 1; return 1;
} }
if ((len < 0) || !s_check_rem(s, len))
{
free_stream(s);
return 1;
}
in_uint8s(s, len); in_uint8s(s, len);
if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_OCTET_STRING, &len) != 0) if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_OCTET_STRING, &len) != 0)
@ -304,6 +351,12 @@ xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self)
return 1; return 1;
} }
if ((len < 0) || !s_check_rem(s, len))
{
free_stream(s);
return 1;
}
in_uint8s(s, len); in_uint8s(s, len);
if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_BOOLEAN, &len) != 0) if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_BOOLEAN, &len) != 0)
@ -312,6 +365,12 @@ xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self)
return 1; return 1;
} }
if ((len < 0) || !s_check_rem(s, len))
{
free_stream(s);
return 1;
}
in_uint8s(s, len); in_uint8s(s, len);
if (xrdp_mcs_parse_domain_params(self, s) != 0) if (xrdp_mcs_parse_domain_params(self, s) != 0)
@ -338,6 +397,19 @@ xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self)
return 1; 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 */ /* make a copy of client mcs data */
init_stream(self->client_mcs_data, len); init_stream(self->client_mcs_data, len);
out_uint8a(self->client_mcs_data, s->p, len); out_uint8a(self->client_mcs_data, s->p, len);
@ -373,6 +445,12 @@ xrdp_mcs_recv_edrq(struct xrdp_mcs *self)
return 1; return 1;
} }
if (!s_check_rem(s, 1))
{
free_stream(s);
return 1;
}
in_uint8(s, opcode); in_uint8(s, opcode);
if ((opcode >> 2) != MCS_EDRQ) if ((opcode >> 2) != MCS_EDRQ)
@ -381,11 +459,22 @@ xrdp_mcs_recv_edrq(struct xrdp_mcs *self)
return 1; return 1;
} }
if (!s_check_rem(s, 4))
{
free_stream(s);
return 1;
}
in_uint8s(s, 2); in_uint8s(s, 2);
in_uint8s(s, 2); in_uint8s(s, 2);
if (opcode & 2) if (opcode & 2)
{ {
if (!s_check_rem(s, 2))
{
free_stream(s);
return 1;
}
in_uint16_be(s, self->userid); in_uint16_be(s, self->userid);
} }
@ -416,6 +505,12 @@ xrdp_mcs_recv_aurq(struct xrdp_mcs *self)
return 1; return 1;
} }
if (!s_check_rem(s, 1))
{
free_stream(s);
return 1;
}
in_uint8(s, opcode); in_uint8(s, opcode);
if ((opcode >> 2) != MCS_AURQ) if ((opcode >> 2) != MCS_AURQ)
@ -426,6 +521,11 @@ xrdp_mcs_recv_aurq(struct xrdp_mcs *self)
if (opcode & 2) if (opcode & 2)
{ {
if (!s_check_rem(s, 2))
{
free_stream(s);
return 1;
}
in_uint16_be(s, self->userid); in_uint16_be(s, self->userid);
} }
@ -491,6 +591,12 @@ xrdp_mcs_recv_cjrq(struct xrdp_mcs *self)
return 1; return 1;
} }
if (!s_check_rem(s, 1))
{
free_stream(s);
return 1;
}
in_uint8(s, opcode); in_uint8(s, opcode);
if ((opcode >> 2) != MCS_CJRQ) if ((opcode >> 2) != MCS_CJRQ)
@ -499,10 +605,21 @@ xrdp_mcs_recv_cjrq(struct xrdp_mcs *self)
return 1; return 1;
} }
if (!s_check_rem(s, 4))
{
free_stream(s);
return 1;
}
in_uint8s(s, 4); in_uint8s(s, 4);
if (opcode & 2) if (opcode & 2)
{ {
if (!s_check_rem(s, 2))
{
free_stream(s);
return 1;
}
in_uint8s(s, 2); in_uint8s(s, 2);
} }

@ -514,6 +514,11 @@ xrdp_rdp_parse_client_mcs_data(struct xrdp_rdp *self)
p = &(self->sec_layer->client_mcs_data); p = &(self->sec_layer->client_mcs_data);
p->p = p->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_uint8s(p, 31);
in_uint16_le(p, self->client_info.width); in_uint16_le(p, self->client_info.width);
in_uint16_le(p, self->client_info.height); in_uint16_le(p, self->client_info.height);
@ -524,6 +529,10 @@ xrdp_rdp_parse_client_mcs_data(struct xrdp_rdp *self)
switch (i) switch (i)
{ {
case 0xca01: case 0xca01:
if (!s_check_rem(p, 6 + 1))
{
return 1;
}
in_uint8s(p, 6); in_uint8s(p, 6);
in_uint8(p, i); in_uint8(p, i);
@ -837,6 +846,11 @@ xrdp_process_capset_general(struct xrdp_rdp *self, struct stream *s,
{ {
int i; int i;
if (len < 10 + 2)
{
g_writeln("xrdp_process_capset_general: error");
return 1;
}
in_uint8s(s, 10); in_uint8s(s, 10);
in_uint16_le(s, i); in_uint16_le(s, i);
/* use_compact_packets is pretty much 'use rdp5' */ /* use_compact_packets is pretty much 'use rdp5' */
@ -858,6 +872,11 @@ xrdp_process_capset_order(struct xrdp_rdp *self, struct stream *s,
int cap_flags; int cap_flags;
DEBUG(("order capabilities")); 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, 20); /* Terminal desc, pad */
in_uint8s(s, 2); /* Cache X granularity */ in_uint8s(s, 2); /* Cache X granularity */
in_uint8s(s, 2); /* Cache Y granularity */ in_uint8s(s, 2); /* Cache Y granularity */
@ -915,13 +934,32 @@ static int APP_CC
xrdp_process_capset_bmpcache(struct xrdp_rdp *self, struct stream *s, xrdp_process_capset_bmpcache(struct xrdp_rdp *self, struct stream *s,
int len) 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; self->client_info.bitmap_cache_version |= 1;
in_uint8s(s, 24); 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.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.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); in_uint16_le(s, self->client_info.cache3_size);
DEBUG(("cache1 entries %d size %d", self->client_info.cache1_entries, DEBUG(("cache1 entries %d size %d", self->client_info.cache1_entries,
self->client_info.cache1_size)); self->client_info.cache1_size));
@ -941,22 +979,30 @@ xrdp_process_capset_bmpcache2(struct xrdp_rdp *self, struct stream *s,
int Bpp = 0; int Bpp = 0;
int i = 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; self->client_info.bitmap_cache_version |= 2;
Bpp = (self->client_info.bpp + 7) / 8; Bpp = (self->client_info.bpp + 7) / 8;
in_uint16_le(s, i); /* cache flags */ in_uint16_le(s, i); /* cache flags */
self->client_info.bitmap_cache_persist_enable = i; self->client_info.bitmap_cache_persist_enable = i;
in_uint8s(s, 2); /* number of caches in set, 3 */ in_uint8s(s, 2); /* number of caches in set, 3 */
in_uint32_le(s, i); 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_entries = i;
self->client_info.cache1_size = 256 * Bpp; self->client_info.cache1_size = 256 * Bpp;
in_uint32_le(s, i); 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_entries = i;
self->client_info.cache2_size = 1024 * Bpp; self->client_info.cache2_size = 1024 * Bpp;
in_uint32_le(s, i); in_uint32_le(s, i);
i = i & 0x7fffffff; 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_entries = i;
self->client_info.cache3_size = 4096 * Bpp; self->client_info.cache3_size = 4096 * Bpp;
DEBUG(("cache1 entries %d size %d", self->client_info.cache1_entries, DEBUG(("cache1 entries %d size %d", self->client_info.cache1_entries,
@ -975,6 +1021,11 @@ xrdp_process_capset_cache_v3_codec_id(struct xrdp_rdp *self, struct stream *s,
{ {
int codec_id; int codec_id;
if (len < 1)
{
g_writeln("xrdp_process_capset_cache_v3_codec_id: error");
return 1;
}
in_uint8(s, codec_id); in_uint8(s, codec_id);
g_writeln("xrdp_process_capset_cache_v3_codec_id: cache_v3_codec_id %d", g_writeln("xrdp_process_capset_cache_v3_codec_id: cache_v3_codec_id %d",
codec_id); codec_id);
@ -992,6 +1043,11 @@ xrdp_process_capset_pointercache(struct xrdp_rdp *self, struct stream *s,
int colorPointerFlag; int colorPointerFlag;
int no_new_cursor; 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; no_new_cursor = self->client_info.pointer_flags & 2;
in_uint16_le(s, colorPointerFlag); in_uint16_le(s, colorPointerFlag);
self->client_info.pointer_flags = colorPointerFlag; self->client_info.pointer_flags = colorPointerFlag;
@ -1028,6 +1084,11 @@ xrdp_process_capset_brushcache(struct xrdp_rdp *self, struct stream *s,
{ {
int code; int code;
if (len < 4)
{
g_writeln("xrdp_process_capset_brushcache: error");
return 1;
}
in_uint32_le(s, code); in_uint32_le(s, code);
self->client_info.brush_cache_code = code; self->client_info.brush_cache_code = code;
return 0; return 0;
@ -1040,12 +1101,11 @@ xrdp_process_offscreen_bmpcache(struct xrdp_rdp *self, struct stream *s,
{ {
int i32; 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; return 1;
} }
in_uint32_le(s, i32); in_uint32_le(s, i32);
self->client_info.offscreen_support_level = i32; self->client_info.offscreen_support_level = i32;
in_uint16_le(s, i32); in_uint16_le(s, i32);
@ -1066,12 +1126,11 @@ xrdp_process_capset_rail(struct xrdp_rdp *self, struct stream *s, int len)
{ {
int i32; 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; return 1;
} }
in_uint32_le(s, i32); in_uint32_le(s, i32);
self->client_info.rail_support_level = i32; self->client_info.rail_support_level = i32;
g_writeln("xrdp_process_capset_rail: rail_support_level %d", g_writeln("xrdp_process_capset_rail: rail_support_level %d",
@ -1085,12 +1144,11 @@ xrdp_process_capset_window(struct xrdp_rdp *self, struct stream *s, int len)
{ {
int i32; 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; return 1;
} }
in_uint32_le(s, i32); in_uint32_le(s, i32);
self->client_info.wnd_support_level = i32; self->client_info.wnd_support_level = i32;
in_uint8(s, i32); in_uint8(s, i32);
@ -1117,14 +1175,32 @@ xrdp_process_capset_codecs(struct xrdp_rdp *self, struct stream *s, int len)
char *codec_guid; char *codec_guid;
char *next_guid; char *next_guid;
if (len < 1)
{
g_writeln("xrdp_process_capset_codecs: error");
return 1;
}
in_uint8(s, codec_count); in_uint8(s, codec_count);
len--;
for (index = 0; index < codec_count; index++) for (index = 0; index < codec_count; index++)
{ {
codec_guid = s->p; codec_guid = s->p;
if (len < 16 + 1 + 2)
{
g_writeln("xrdp_process_capset_codecs: error");
return 1;
}
in_uint8s(s, 16); in_uint8s(s, 16);
in_uint8(s, codec_id); in_uint8(s, codec_id);
in_uint16_le(s, codec_properties_length); 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; next_guid = s->p + codec_properties_length;
if (g_memcmp(codec_guid, XR_CODEC_GUID_NSCODEC, 16) == 0) if (g_memcmp(codec_guid, XR_CODEC_GUID_NSCODEC, 16) == 0)
@ -1190,9 +1266,19 @@ xrdp_rdp_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
for (index = 0; index < num_caps; index++) for (index = 0; index < num_caps; index++)
{ {
p = s->p; 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, type);
in_uint16_le(s, len); 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) switch (type)
{ {
case RDP_CAPSET_GENERAL: /* 1 */ case RDP_CAPSET_GENERAL: /* 1 */
@ -1278,7 +1364,7 @@ xrdp_rdp_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
break; break;
} }
s->p = p + len; s->p = p + len + 4;
} }
DEBUG(("out xrdp_rdp_process_confirm_active")); DEBUG(("out xrdp_rdp_process_confirm_active"));
@ -1305,12 +1391,20 @@ xrdp_rdp_process_data_input(struct xrdp_rdp *self, struct stream *s)
int param2; int param2;
int time; int time;
if (!s_check_rem(s, 4))
{
return 1;
}
in_uint16_le(s, num_events); in_uint16_le(s, num_events);
in_uint8s(s, 2); /* pad */ in_uint8s(s, 2); /* pad */
DEBUG(("in xrdp_rdp_process_data_input %d events", num_events)); DEBUG(("in xrdp_rdp_process_data_input %d events", num_events));
for (index = 0; index < num_events; index++) for (index = 0; index < num_events; index++)
{ {
if (!s_check_rem(s, 12))
{
return 1;
}
in_uint32_le(s, time); in_uint32_le(s, time);
in_uint16_le(s, msg_type); in_uint16_le(s, msg_type);
in_uint16_le(s, device_flags); in_uint16_le(s, device_flags);

@ -331,12 +331,20 @@ unicode_in(struct stream *s, int uni_len, char *dst, int dst_len)
break; break;
} }
if (!s_check_rem(s, 2))
{
return 1;
}
in_uint8(s, dst[dst_index]); in_uint8(s, dst[dst_index]);
in_uint8s(s, 1); in_uint8s(s, 1);
dst_index++; dst_index++;
src_index += 2; src_index += 2;
} }
if (!s_check_rem(s, 2))
{
return 1;
}
in_uint8s(s, 2); in_uint8s(s, 2);
return 0; return 0;
} }
@ -359,6 +367,10 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
/* initialize (zero out) local variables */ /* initialize (zero out) local variables */
g_memset(tmpdata, 0, sizeof(char) * 256); g_memset(tmpdata, 0, sizeof(char) * 256);
if (!s_check_rem(s, 8))
{
return 1;
}
in_uint8s(s, 4); in_uint8s(s, 4);
in_uint32_le(s, flags); in_uint32_le(s, flags);
DEBUG(("in xrdp_sec_process_logon_info flags $%x", flags)); DEBUG(("in xrdp_sec_process_logon_info flags $%x", flags));
@ -398,6 +410,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); in_uint16_le(s, len_domain);
if (len_domain > 511) if (len_domain > 511)
@ -406,6 +422,10 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
return 1; return 1;
} }
if (!s_check_rem(s, 2))
{
return 1;
}
in_uint16_le(s, len_user); in_uint16_le(s, len_user);
if (len_user > 511) if (len_user > 511)
@ -414,6 +434,10 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
return 1; return 1;
} }
if (!s_check_rem(s, 2))
{
return 1;
}
in_uint16_le(s, len_password); in_uint16_le(s, len_password);
if (len_password > 511) if (len_password > 511)
@ -422,6 +446,10 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
return 1; return 1;
} }
if (!s_check_rem(s, 2))
{
return 1;
}
in_uint16_le(s, len_program); in_uint16_le(s, len_program);
if (len_program > 511) if (len_program > 511)
@ -430,6 +458,10 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
return 1; return 1;
} }
if (!s_check_rem(s, 2))
{
return 1;
}
in_uint16_le(s, len_directory); in_uint16_le(s, len_directory);
if (len_directory > 511) if (len_directory > 511)
@ -438,35 +470,75 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
return 1; 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)); 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)); DEBUG(("username %s", self->rdp_layer->client_info.username));
if (flags & RDP_LOGON_AUTO) 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")); DEBUG(("flag RDP_LOGON_AUTO found"));
} }
else else
{ {
if (!s_check_rem(s, len_password + 2))
{
return 1;
}
in_uint8s(s, len_password + 2); in_uint8s(s, len_password + 2);
if (self->rdp_layer->client_info.require_credentials) 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 */ 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)); 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)); DEBUG(("directory %s", self->rdp_layer->client_info.directory));
if (flags & RDP_LOGON_BLOB) if (flags & RDP_LOGON_BLOB)
{ {
if (!s_check_rem(s, 4))
{
return 1;
}
in_uint8s(s, 2); /* unknown */ in_uint8s(s, 2); /* unknown */
in_uint16_le(s, len_ip); 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); in_uint16_le(s, len_dll);
unicode_in(s, len_dll - 2, tmpdata, 255); 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 timetone */ in_uint32_le(s, tzone); /* len of timetone */
in_uint8s(s, 62); /* skip */ in_uint8s(s, 62); /* skip */
in_uint8s(s, 22); /* skip misc. */ in_uint8s(s, 22); /* skip misc. */
@ -676,17 +748,29 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan)
return 1; return 1;
} }
if (!s_check_rem(s, 4))
{
return 1;
}
in_uint32_le(s, flags); in_uint32_le(s, flags);
DEBUG((" in xrdp_sec_recv flags $%x", flags)); DEBUG((" in xrdp_sec_recv flags $%x", flags));
if (flags & SEC_ENCRYPT) /* 0x08 */ if (flags & SEC_ENCRYPT) /* 0x08 */
{ {
if (!s_check_rem(s, 8))
{
return 1;
}
in_uint8s(s, 8); /* signature */ in_uint8s(s, 8); /* signature */
xrdp_sec_decrypt(self, s->p, (int)(s->end - s->p)); xrdp_sec_decrypt(self, s->p, (int)(s->end - s->p));
} }
if (flags & SEC_CLIENT_RANDOM) /* 0x01 */ if (flags & SEC_CLIENT_RANDOM) /* 0x01 */
{ {
if (!s_check_rem(s, 4 + 64))
{
return 1;
}
in_uint32_le(s, len); in_uint32_le(s, len);
in_uint8a(s, self->client_crypt_random, 64); in_uint8a(s, self->client_crypt_random, 64);
xrdp_sec_rsa_op(self->client_random, self->client_crypt_random, xrdp_sec_rsa_op(self->client_random, self->client_crypt_random,
@ -836,16 +920,30 @@ xrdp_sec_process_mcs_data_channels(struct xrdp_sec *self, struct stream *s)
return 0; return 0;
} }
if (!s_check_rem(s, 4))
{
return 1;
}
in_uint32_le(s, num_channels); in_uint32_le(s, num_channels);
if (num_channels > 31)
{
return 1;
}
for (index = 0; index < num_channels; index++) for (index = 0; index < num_channels; index++)
{ {
channel_item = (struct mcs_channel_item *) channel_item = (struct mcs_channel_item *)
g_malloc(sizeof(struct mcs_channel_item), 1); g_malloc(sizeof(struct mcs_channel_item), 1);
if (!s_check_rem(s, 12))
{
return 1;
}
in_uint8a(s, channel_item->name, 8); in_uint8a(s, channel_item->name, 8);
in_uint32_le(s, channel_item->flags); in_uint32_le(s, channel_item->flags);
channel_item->chanid = MCS_GLOBAL_CHANNEL + (index + 1); 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, DEBUG(("got channel flags %8.8x name %s", channel_item->flags,
channel_item->name)); channel_item->name));
} }
@ -864,10 +962,14 @@ xrdp_sec_process_mcs_data(struct xrdp_sec *self)
int tag = 0; int tag = 0;
int size = 0; int size = 0;
s = &self->client_mcs_data; s = &(self->client_mcs_data);
/* set p to beginning */ /* set p to beginning */
s->p = s->data; s->p = s->data;
/* skip header */ /* skip header */
if (!s_check_rem(s, 23))
{
return 1;
}
in_uint8s(s, 23); in_uint8s(s, 23);
while (s_check_rem(s, 4)) while (s_check_rem(s, 4))
@ -890,7 +992,10 @@ xrdp_sec_process_mcs_data(struct xrdp_sec *self)
case SEC_TAG_CLI_CRYPT: case SEC_TAG_CLI_CRYPT:
break; break;
case SEC_TAG_CLI_CHANNELS: 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; break;
case SEC_TAG_CLI_4: case SEC_TAG_CLI_4:
break; break;
@ -999,7 +1104,7 @@ xrdp_sec_out_mcs_data(struct xrdp_sec *self)
/*****************************************************************************/ /*****************************************************************************/
/* process the mcs client data we received from the mcs layer */ /* 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) xrdp_sec_in_mcs_data(struct xrdp_sec *self)
{ {
struct stream *s = (struct stream *)NULL; struct stream *s = (struct stream *)NULL;
@ -1011,6 +1116,10 @@ xrdp_sec_in_mcs_data(struct xrdp_sec *self)
s = &(self->client_mcs_data); s = &(self->client_mcs_data);
/* get hostname, its unicode */ /* get hostname, its unicode */
s->p = s->data; s->p = s->data;
if (!s_check_rem(s, 47))
{
return 1;
}
in_uint8s(s, 47); in_uint8s(s, 47);
g_memset(client_info->hostname, 0, 32); g_memset(client_info->hostname, 0, 32);
c = 1; c = 1;
@ -1018,6 +1127,10 @@ xrdp_sec_in_mcs_data(struct xrdp_sec *self)
while (index < 16 && c != 0) while (index < 16 && c != 0)
{ {
if (!s_check_rem(s, 2))
{
return 1;
}
in_uint8(s, c); in_uint8(s, c);
in_uint8s(s, 1); in_uint8s(s, 1);
client_info->hostname[index] = c; client_info->hostname[index] = c;
@ -1026,13 +1139,22 @@ xrdp_sec_in_mcs_data(struct xrdp_sec *self)
/* get build */ /* get build */
s->p = s->data; s->p = s->data;
if (!s_check_rem(s, 43 + 4))
{
return 1;
}
in_uint8s(s, 43); in_uint8s(s, 43);
in_uint32_le(s, client_info->build); in_uint32_le(s, client_info->build);
/* get keylayout */ /* get keylayout */
s->p = s->data; s->p = s->data;
if (!s_check_rem(s, 39 + 4))
{
return 1;
}
in_uint8s(s, 39); in_uint8s(s, 39);
in_uint32_le(s, client_info->keylayout); in_uint32_le(s, client_info->keylayout);
s->p = s->data; s->p = s->data;
return 0;
} }
/*****************************************************************************/ /*****************************************************************************/
@ -1105,7 +1227,10 @@ xrdp_sec_incoming(struct xrdp_sec *self)
(int)(self->server_mcs_data.end - self->server_mcs_data.data)); (int)(self->server_mcs_data.end - self->server_mcs_data.data));
#endif #endif
DEBUG((" out xrdp_sec_incoming")); DEBUG((" out xrdp_sec_incoming"));
xrdp_sec_in_mcs_data(self); if (xrdp_sec_in_mcs_data(self) != 0)
{
return 1;
}
return 0; return 0;
} }

@ -471,6 +471,8 @@ int
rdpup_add_os_bitmap(PixmapPtr pixmap, rdpPixmapPtr priv); rdpup_add_os_bitmap(PixmapPtr pixmap, rdpPixmapPtr priv);
int int
rdpup_remove_os_bitmap(int rdpindex); rdpup_remove_os_bitmap(int rdpindex);
int
rdpup_update_os_use(int rdpindex);
void void
rdpup_get_screen_image_rect(struct image_data* id); rdpup_get_screen_image_rect(struct image_data* id);
void void

@ -429,6 +429,8 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
pSrcPixmap = (PixmapPtr)pSrc; pSrcPixmap = (PixmapPtr)pSrc;
pSrcPriv = GETPIXPRIV(pSrcPixmap); pSrcPriv = GETPIXPRIV(pSrcPixmap);
LLOGLN(10, ("rdpCopyArea: 3 %d %d", pSrcPixmap->usage_hint, pSrcPriv->is_scratch));
if (xrdp_is_os(pSrcPixmap, pSrcPriv)) if (xrdp_is_os(pSrcPixmap, pSrcPriv))
{ {
if (pDst->type == DRAWABLE_WINDOW) if (pDst->type == DRAWABLE_WINDOW)
@ -468,7 +470,7 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
} }
else else
{ {
LLOGLN(10, ("rdpCopyArea: 2")); LLOGLN(10, ("rdpCopyArea: 2 %d %d", pSrcPixmap->usage_hint, pSrcPriv->is_scratch));
} }
} }
@ -495,7 +497,7 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
LLOGLN(10, ("rdpCopyArea: getting dirty")); LLOGLN(10, ("rdpCopyArea: getting dirty"));
pDstPriv->is_dirty = 1; pDstPriv->is_dirty = 1;
pDirtyPriv = pDstPriv; pDirtyPriv = pDstPriv;
dirty_type = RDI_IMGLL; dirty_type = RDI_IMGLY;
} }
else else
{ {
@ -525,7 +527,7 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
LLOGLN(10, ("rdpCopyArea: getting dirty")); LLOGLN(10, ("rdpCopyArea: getting dirty"));
g_screenPriv.is_dirty = 1; g_screenPriv.is_dirty = 1;
pDirtyPriv = &g_screenPriv; pDirtyPriv = &g_screenPriv;
dirty_type = RDI_IMGLL; dirty_type = RDI_IMGLY;
} }
else else
{ {
@ -541,6 +543,8 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
return rv; return rv;
} }
LLOGLN(10, ("rdpCopyArea: post_process"));
RegionInit(&clip_reg, NullBox, 0); RegionInit(&clip_reg, NullBox, 0);
cd = rdp_get_clip(&clip_reg, pDst, pGC); cd = rdp_get_clip(&clip_reg, pDst, pGC);

@ -739,13 +739,12 @@ rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth,
width, org_width, depth, g_rdpScreen.depth)); width, org_width, depth, g_rdpScreen.depth));
pScreen->CreatePixmap = g_rdpScreen.CreatePixmap; pScreen->CreatePixmap = g_rdpScreen.CreatePixmap;
rv = pScreen->CreatePixmap(pScreen, width, height, depth, usage_hint); rv = pScreen->CreatePixmap(pScreen, width, height, depth, usage_hint);
pScreen->CreatePixmap = rdpCreatePixmap;
priv = GETPIXPRIV(rv); priv = GETPIXPRIV(rv);
priv->rdpindex = -1; priv->rdpindex = -1;
priv->con_number = g_con_number;
priv->kind_width = width; priv->kind_width = width;
pScreen->ModifyPixmapHeader(rv, org_width, 0, 0, 0, 0, 0); pScreen->ModifyPixmapHeader(rv, org_width, 0, 0, 0, 0, 0);
pScreen->CreatePixmap = rdpCreatePixmap; if ((org_width == 0) && (height == 0))
if (org_width == 0 && height == 0)
{ {
priv->is_scratch = 1; priv->is_scratch = 1;
} }
@ -793,14 +792,19 @@ xrdp_is_os(PixmapPtr pix, rdpPixmapPtr priv)
int height; int height;
struct image_data id; struct image_data id;
if (!XRDP_IS_OS(priv)) if (XRDP_IS_OS(priv))
{
/* update time stamp */
rdpup_update_os_use(priv->rdpindex);
}
else
{ {
width = pix->drawable.width; width = pix->drawable.width;
height = pix->drawable.height; height = pix->drawable.height;
if ((pix->usage_hint == 0) && if ((pix->usage_hint == 0) &&
(pix->drawable.depth >= g_rdpScreen.depth) && (pix->drawable.depth >= g_rdpScreen.depth) &&
(width > 0) && (height > 0) && (priv->kind_width > 0) && (width > 0) && (height > 0) && (priv->kind_width > 0) &&
(priv->is_scratch == 0)) (priv->is_scratch == 0) && (priv->use_count >= 0))
{ {
LLOGLN(10, ("%d %d", priv->kind_width, pix->drawable.width)); LLOGLN(10, ("%d %d", priv->kind_width, pix->drawable.width));
priv->rdpindex = rdpup_add_os_bitmap(pix, priv); priv->rdpindex = rdpup_add_os_bitmap(pix, priv);
@ -815,8 +819,12 @@ xrdp_is_os(PixmapPtr pix, rdpPixmapPtr priv)
box.y2 = height; box.y2 = height;
if (g_do_dirty_os) if (g_do_dirty_os)
{ {
LLOGLN(10, ("xrdp_is_os: priv->con_number %d g_con_number %d",
priv->con_number, g_con_number));
LLOGLN(10, ("xrdp_is_os: priv->use_count %d", priv->use_count));
if (priv->con_number != g_con_number) if (priv->con_number != g_con_number)
{ {
LLOGLN(10, ("xrdp_is_os: queuing invalidating all"));
draw_item_remove_all(priv); draw_item_remove_all(priv);
RegionInit(&reg1, &box, 0); RegionInit(&reg1, &box, 0);
draw_item_add_img_region(priv, &reg1, GXcopy, RDI_IMGLL, 16); draw_item_add_img_region(priv, &reg1, GXcopy, RDI_IMGLL, 16);
@ -1350,7 +1358,7 @@ rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
rdpPixmapRec *pDirtyPriv; rdpPixmapRec *pDirtyPriv;
struct image_data id; struct image_data id;
LLOGLN(10, ("rdpComposite:")); LLOGLN(10, ("rdpComposite: op %d width %d height %d", op, width, height));
ps = GetPictureScreen(g_pScreen); ps = GetPictureScreen(g_pScreen);
ps->Composite = g_rdpScreen.Composite; ps->Composite = g_rdpScreen.Composite;
ps->Composite(op, pSrc, pMask, pDst, xSrc, ySrc, ps->Composite(op, pSrc, pMask, pDst, xSrc, ySrc,
@ -1424,6 +1432,8 @@ rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
return; return;
} }
LLOGLN(10, ("rdpComposite: post_process"));
if (pDst->pCompositeClip != 0) if (pDst->pCompositeClip != 0)
{ {
box.x1 = p->x + xDst; box.x1 = p->x + xDst;

@ -39,6 +39,9 @@ static char *g_shmemptr = 0;
static int g_shmem_lineBytes = 0; static int g_shmem_lineBytes = 0;
static RegionPtr g_shm_reg = 0; static RegionPtr g_shm_reg = 0;
static int g_rect_id_ack = 0;
static int g_rect_id = 0;
static int g_listen_sck = 0; static int g_listen_sck = 0;
static int g_sck = 0; static int g_sck = 0;
static int g_sck_closed = 0; static int g_sck_closed = 0;
@ -82,9 +85,11 @@ struct rdpup_os_bitmap
int stamp; int stamp;
}; };
#define MAX_OS_BYTES (16 * 1024 * 1024)
static struct rdpup_os_bitmap *g_os_bitmaps = 0; static struct rdpup_os_bitmap *g_os_bitmaps = 0;
static int g_max_os_bitmaps = 0; static int g_max_os_bitmaps = 0;
static int g_os_bitmap_stamp = 0; static int g_os_bitmap_stamp = 0;
static int g_os_bitmap_alloc_size = 0;
static int g_pixmap_byte_total = 0; static int g_pixmap_byte_total = 0;
static int g_pixmap_num_used = 0; static int g_pixmap_num_used = 0;
@ -217,6 +222,7 @@ rdpup_disconnect(void)
} }
} }
} }
g_os_bitmap_alloc_size = 0;
g_max_os_bitmaps = 0; g_max_os_bitmaps = 0;
g_free(g_os_bitmaps); g_free(g_os_bitmaps);
@ -233,6 +239,7 @@ rdpup_add_os_bitmap(PixmapPtr pixmap, rdpPixmapPtr priv)
int rv; int rv;
int oldest; int oldest;
int oldest_index; int oldest_index;
int this_bytes;
if (!g_connected) if (!g_connected)
{ {
@ -244,6 +251,17 @@ rdpup_add_os_bitmap(PixmapPtr pixmap, rdpPixmapPtr priv)
return -1; return -1;
} }
this_bytes = pixmap->devKind * pixmap->drawable.height;
if (this_bytes > MAX_OS_BYTES)
{
LLOGLN(10, ("rdpup_add_os_bitmap: error, too big this_bytes %d "
"width %d height %d", this_bytes,
pixmap->drawable.height, pixmap->drawable.height));
return -1;
}
oldest = 0x7fffffff;
oldest_index = -1;
rv = -1; rv = -1;
index = 0; index = 0;
@ -260,42 +278,77 @@ rdpup_add_os_bitmap(PixmapPtr pixmap, rdpPixmapPtr priv)
rv = index; rv = index;
break; break;
} }
else
{
if (g_os_bitmaps[index].stamp < oldest)
{
oldest = g_os_bitmaps[index].stamp;
oldest_index = index;
}
}
index++; index++;
} }
if (rv == -1) if (rv == -1)
{ {
if (oldest_index == -1)
{
LLOGLN(0, ("rdpup_add_os_bitmap: error"));
}
else
{
rdpup_remove_os_bitmap(oldest_index);
g_os_bitmaps[index].used = 1;
g_os_bitmaps[index].pixmap = pixmap;
g_os_bitmaps[index].priv = priv;
g_os_bitmaps[index].stamp = g_os_bitmap_stamp;
g_os_bitmap_stamp++;
g_pixmap_num_used++;
rv = oldest_index;
}
}
if (rv < 0)
{
return rv;
}
g_os_bitmap_alloc_size += this_bytes;
LLOGLN(10, ("rdpup_add_os_bitmap: this_bytes %d g_os_bitmap_alloc_size %d",
this_bytes, g_os_bitmap_alloc_size));
while (g_os_bitmap_alloc_size > MAX_OS_BYTES)
{
LLOGLN(10, ("rdpup_add_os_bitmap: must delete g_pixmap_num_used %d",
g_pixmap_num_used));
/* find oldest */ /* find oldest */
oldest = 0x7fffffff; oldest = 0x7fffffff;
oldest_index = 0; oldest_index = -1;
index = 0; index = 0;
while (index < g_max_os_bitmaps) while (index < g_max_os_bitmaps)
{ {
if (g_os_bitmaps[index].stamp < oldest) if (g_os_bitmaps[index].used && g_os_bitmaps[index].stamp < oldest)
{ {
oldest = g_os_bitmaps[index].stamp; oldest = g_os_bitmaps[index].stamp;
oldest_index = index; oldest_index = index;
} }
index++; index++;
} }
if (oldest_index == -1)
LLOGLN(10, ("rdpup_add_os_bitmap: evicting old, oldest_index %d", oldest_index)); {
/* evict old */ LLOGLN(0, ("rdpup_add_os_bitmap: error 1"));
g_os_bitmaps[oldest_index].priv->status = 0; break;
g_os_bitmaps[oldest_index].priv->con_number = 0; }
/* set new */ if (oldest_index == rv)
g_os_bitmaps[oldest_index].pixmap = pixmap; {
g_os_bitmaps[oldest_index].priv = priv; LLOGLN(0, ("rdpup_add_os_bitmap: error 2"));
g_os_bitmaps[oldest_index].stamp = g_os_bitmap_stamp; break;
g_os_bitmap_stamp++; }
rv = oldest_index; rdpup_remove_os_bitmap(oldest_index);
rdpup_delete_os_surface(oldest_index);
} }
LLOGLN(10, ("rdpup_add_os_bitmap: new bitmap index %d", rv)); LLOGLN(10, ("rdpup_add_os_bitmap: new bitmap index %d", rv));
LLOGLN(10, (" g_pixmap_num_used %d", g_pixmap_num_used)); LLOGLN(10, ("rdpup_add_os_bitmap: g_pixmap_num_used %d "
"g_os_bitmap_stamp 0x%8.8x", g_pixmap_num_used, g_os_bitmap_stamp));
return rv; return rv;
} }
@ -303,8 +356,12 @@ rdpup_add_os_bitmap(PixmapPtr pixmap, rdpPixmapPtr priv)
int int
rdpup_remove_os_bitmap(int rdpindex) rdpup_remove_os_bitmap(int rdpindex)
{ {
PixmapPtr pixmap;
rdpPixmapPtr priv;
int this_bytes;
LLOGLN(10, ("rdpup_remove_os_bitmap: index %d stamp %d", LLOGLN(10, ("rdpup_remove_os_bitmap: index %d stamp %d",
rdpindex, g_os_bitmaps[rdpindex].stamp)); rdpindex, g_os_bitmaps[rdpindex].stamp));
if (g_os_bitmaps == 0) if (g_os_bitmaps == 0)
{ {
@ -318,16 +375,66 @@ rdpup_remove_os_bitmap(int rdpindex)
if (g_os_bitmaps[rdpindex].used) if (g_os_bitmaps[rdpindex].used)
{ {
pixmap = g_os_bitmaps[rdpindex].pixmap;
priv = g_os_bitmaps[rdpindex].priv;
draw_item_remove_all(priv);
this_bytes = pixmap->devKind * pixmap->drawable.height;
g_os_bitmap_alloc_size -= this_bytes;
LLOGLN(10, ("rdpup_remove_os_bitmap: this_bytes %d "
"g_os_bitmap_alloc_size %d", this_bytes,
g_os_bitmap_alloc_size));
g_os_bitmaps[rdpindex].used = 0; g_os_bitmaps[rdpindex].used = 0;
g_os_bitmaps[rdpindex].pixmap = 0; g_os_bitmaps[rdpindex].pixmap = 0;
g_os_bitmaps[rdpindex].priv = 0; g_os_bitmaps[rdpindex].priv = 0;
g_pixmap_num_used--; g_pixmap_num_used--;
priv->status = 0;
priv->con_number = 0;
priv->use_count = 0;
}
else
{
LLOGLN(0, ("rdpup_remove_os_bitmap: error"));
} }
LLOGLN(10, (" g_pixmap_num_used %d", g_pixmap_num_used)); LLOGLN(10, (" g_pixmap_num_used %d", g_pixmap_num_used));
return 0; return 0;
} }
/*****************************************************************************/
int
rdpup_update_os_use(int rdpindex)
{
PixmapPtr pixmap;
rdpPixmapPtr priv;
int this_bytes;
LLOGLN(10, ("rdpup_update_use: index %d stamp %d",
rdpindex, g_os_bitmaps[rdpindex].stamp));
if (g_os_bitmaps == 0)
{
return 1;
}
if ((rdpindex < 0) && (rdpindex >= g_max_os_bitmaps))
{
return 1;
}
if (g_os_bitmaps[rdpindex].used)
{
g_os_bitmaps[rdpindex].stamp = g_os_bitmap_stamp;
g_os_bitmap_stamp++;
}
else
{
LLOGLN(0, ("rdpup_update_use: error rdpindex %d", rdpindex));
}
return 0;
}
/*****************************************************************************/ /*****************************************************************************/
/* returns error */ /* returns error */
static int static int
@ -433,7 +540,14 @@ rdpDeferredUpdateCallback(OsTimerPtr timer, CARD32 now, pointer arg)
if (g_do_dirty_ons) if (g_do_dirty_ons)
{ {
rdpup_check_dirty_screen(&g_screenPriv); if (g_rect_id == g_rect_id_ack)
{
rdpup_check_dirty_screen(&g_screenPriv);
}
else
{
LLOGLN(0, ("rdpDeferredUpdateCallback: skipping"));
}
} }
else else
{ {
@ -909,11 +1023,13 @@ rdpup_process_msg(struct stream *s)
{ {
LLOGLN(10, ("rdpup_process_msg: got msg 105")); LLOGLN(10, ("rdpup_process_msg: got msg 105"));
in_uint32_le(s, flags); in_uint32_le(s, flags);
in_uint32_le(s, g_rect_id_ack);
in_uint32_le(s, x); in_uint32_le(s, x);
in_uint32_le(s, y); in_uint32_le(s, y);
in_uint32_le(s, cx); in_uint32_le(s, cx);
in_uint32_le(s, cy); in_uint32_le(s, cy);
LLOGLN(10, (" %d %d %d %d", x, y, cx ,cy)); LLOGLN(10, (" %d %d %d %d", x, y, cx ,cy));
LLOGLN(10, (" rect_id %d rect_id_ack %d", g_rect_id, g_rect_id_ack));
box.x1 = x; box.x1 = x;
box.y1 = y; box.y1 = y;
@ -926,6 +1042,8 @@ rdpup_process_msg(struct stream *s)
RegionUninit(&reg); RegionUninit(&reg);
} }
else else
{ {
rdpLog("unknown message type in rdpup_process_msg %d\n", msg_type); rdpLog("unknown message type in rdpup_process_msg %d\n", msg_type);
@ -1870,7 +1988,7 @@ rdpup_send_area(struct image_data *id, int x, int y, int w, int h)
d += id->shmem_lineBytes; d += id->shmem_lineBytes;
ly += 1; ly += 1;
} }
size = 32; size = 36;
rdpup_pre_check(size); rdpup_pre_check(size);
out_uint16_le(g_out_s, 60); out_uint16_le(g_out_s, 60);
out_uint16_le(g_out_s, size); out_uint16_le(g_out_s, size);
@ -1880,6 +1998,8 @@ rdpup_send_area(struct image_data *id, int x, int y, int w, int h)
out_uint16_le(g_out_s, w); out_uint16_le(g_out_s, w);
out_uint16_le(g_out_s, h); out_uint16_le(g_out_s, h);
out_uint32_le(g_out_s, 0); out_uint32_le(g_out_s, 0);
g_rect_id++;
out_uint32_le(g_out_s, g_rect_id);
out_uint32_le(g_out_s, id->shmem_id); out_uint32_le(g_out_s, id->shmem_id);
out_uint32_le(g_out_s, id->shmem_offset); out_uint32_le(g_out_s, id->shmem_offset);
out_uint16_le(g_out_s, id->width); out_uint16_le(g_out_s, id->width);
@ -2128,10 +2248,6 @@ rdpup_check_dirty(PixmapPtr pDirtyPixmap, rdpPixmapRec *pDirtyPriv)
return 0; return 0;
} }
/* update use time / count */
g_os_bitmaps[pDirtyPriv->rdpindex].stamp = g_os_bitmap_stamp;
g_os_bitmap_stamp++;
LLOGLN(10, ("rdpup_check_dirty: got dirty")); LLOGLN(10, ("rdpup_check_dirty: got dirty"));
rdpup_switch_os_surface(pDirtyPriv->rdpindex); rdpup_switch_os_surface(pDirtyPriv->rdpindex);
rdpup_get_pixmap_image_rect(pDirtyPixmap, &id); rdpup_get_pixmap_image_rect(pDirtyPixmap, &id);
@ -2293,8 +2409,8 @@ rdpup_check_dirty_screen(rdpPixmapRec *pDirtyPriv)
for (index = 0; index < count; index++) for (index = 0; index < count; index++)
{ {
box = REGION_RECTS(di->reg)[index]; box = REGION_RECTS(di->reg)[index];
LLOGLN(10, (" RDI_IMGLL %d %d %d %d", box.x1, box.y1, LLOGLN(10, (" RDI_IMGLL x %d y %d w %d h %d", box.x1, box.y1,
box.x2, box.y2)); box.x2 - box.x1, box.y2 - box.y1));
rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1,
box.y2 - box.y1); box.y2 - box.y1);
} }

@ -27,8 +27,8 @@
#include "trans.h" #include "trans.h"
#include "list.h" #include "list.h"
#include "libxrdpinc.h" #include "libxrdpinc.h"
#include "xrdp_types.h"
#include "xrdp_constants.h" #include "xrdp_constants.h"
#include "xrdp_types.h"
#include "defines.h" #include "defines.h"
#include "os_calls.h" #include "os_calls.h"
#include "ssl_calls.h" #include "ssl_calls.h"

@ -33,16 +33,27 @@ xrdp_cache_create(struct xrdp_wm *owner,
self->wm = owner; self->wm = owner;
self->session = session; self->session = session;
self->use_bitmap_comp = client_info->use_bitmap_comp; self->use_bitmap_comp = client_info->use_bitmap_comp;
self->cache1_entries = client_info->cache1_entries;
self->cache1_entries = MIN(XRDP_MAX_BITMAP_CACHE_IDX,
client_info->cache1_entries);
self->cache1_entries = MAX(self->cache1_entries, 0);
self->cache1_size = client_info->cache1_size; self->cache1_size = client_info->cache1_size;
self->cache2_entries = client_info->cache2_entries;
self->cache2_entries = MIN(XRDP_MAX_BITMAP_CACHE_IDX,
client_info->cache2_entries);
self->cache2_entries = MAX(self->cache2_entries, 0);
self->cache2_size = client_info->cache2_size; self->cache2_size = client_info->cache2_size;
self->cache3_entries = client_info->cache3_entries;
self->cache3_entries = MIN(XRDP_MAX_BITMAP_CACHE_IDX,
client_info->cache3_entries);
self->cache3_entries = MAX(self->cache3_entries, 0);
self->cache3_size = client_info->cache3_size; self->cache3_size = client_info->cache3_size;
self->bitmap_cache_persist_enable = client_info->bitmap_cache_persist_enable; self->bitmap_cache_persist_enable = client_info->bitmap_cache_persist_enable;
self->bitmap_cache_version = client_info->bitmap_cache_version; self->bitmap_cache_version = client_info->bitmap_cache_version;
self->pointer_cache_entries = client_info->pointer_cache_entries; self->pointer_cache_entries = client_info->pointer_cache_entries;
self->xrdp_os_del_list = list_create(); self->xrdp_os_del_list = list_create();
return self; return self;
} }

@ -203,6 +203,9 @@ xrdp_process_main_loop(struct xrdp_process *self)
else else
{ {
g_writeln("xrdp_process_main_loop: libxrdp_process_incomming failed"); g_writeln("xrdp_process_main_loop: libxrdp_process_incomming failed");
/* this will try to send a disconnect,
maybe should check that connection got far enough */
libxrdp_disconnect(self->session);
} }
/* Run end in module */ /* Run end in module */
xrdp_process_mod_end(self); xrdp_process_mod_end(self);

@ -195,7 +195,8 @@ struct xrdp_cache
struct xrdp_palette_item palette_items[6]; struct xrdp_palette_item palette_items[6];
/* bitmap */ /* bitmap */
int bitmap_stamp; int bitmap_stamp;
struct xrdp_bitmap_item bitmap_items[3][2000]; struct xrdp_bitmap_item bitmap_items[XRDP_MAX_BITMAP_CACHE_ID]
[XRDP_MAX_BITMAP_CACHE_IDX];
int use_bitmap_comp; int use_bitmap_comp;
int cache1_entries; int cache1_entries;
int cache1_size; int cache1_size;

@ -516,7 +516,8 @@ process_server_set_pointer_ex(struct mod *mod, struct stream *s)
/******************************************************************************/ /******************************************************************************/
/* return error */ /* return error */
static int APP_CC static int APP_CC
send_paint_rect_ack(struct mod *mod, int flags, int x, int y, int cx, int cy) send_paint_rect_ack(struct mod *mod, int flags, int x, int y, int cx, int cy,
int frame_id)
{ {
int len; int len;
struct stream *s; struct stream *s;
@ -526,6 +527,7 @@ send_paint_rect_ack(struct mod *mod, int flags, int x, int y, int cx, int cy)
s_push_layer(s, iso_hdr, 4); s_push_layer(s, iso_hdr, 4);
out_uint16_le(s, 105); out_uint16_le(s, 105);
out_uint32_le(s, flags); out_uint32_le(s, flags);
out_uint32_le(s, frame_id);
out_uint32_le(s, x); out_uint32_le(s, x);
out_uint32_le(s, y); out_uint32_le(s, y);
out_uint32_le(s, cx); out_uint32_le(s, cx);
@ -568,6 +570,7 @@ lib_mod_process_orders(struct mod *mod, int type, struct stream *s)
int flags; int flags;
int shmem_id; int shmem_id;
int shmem_offset; int shmem_offset;
int frame_id;
char *bmpdata; char *bmpdata;
char cur_data[32 * (32 * 3)]; char cur_data[32 * (32 * 3)];
char cur_mask[32 * (32 / 8)]; char cur_mask[32 * (32 / 8)];
@ -699,6 +702,7 @@ lib_mod_process_orders(struct mod *mod, int type, struct stream *s)
in_uint16_le(s, cx); in_uint16_le(s, cx);
in_uint16_le(s, cy); in_uint16_le(s, cy);
in_uint32_le(s, flags); in_uint32_le(s, flags);
in_uint32_le(s, frame_id);
in_uint32_le(s, shmem_id); in_uint32_le(s, shmem_id);
in_uint32_le(s, shmem_offset); in_uint32_le(s, shmem_offset);
in_uint16_le(s, width); in_uint16_le(s, width);
@ -728,7 +732,7 @@ lib_mod_process_orders(struct mod *mod, int type, struct stream *s)
{ {
rv = 1; rv = 1;
} }
send_paint_rect_ack(mod, flags, x, y, cx, cy); send_paint_rect_ack(mod, flags, x, y, cx, cy, frame_id);
break; break;
default: default:

Loading…
Cancel
Save