RDP compositor: fixes for multiple connections, mstsc and FreeRDP master compilation

This patch fixes the problem reported on the mailing list
(http://lists.freedesktop.org/archives/wayland-devel/2015-January/019575.html).
All certificate and key paths were not copied when given to FreeRDP, so they
were freed when the peer was disconnecting. And so the next connection was failing.

All the initialization stuffs have been moved to the activate callback, as when it is
called the peer is ready for graphics.

We also differ the creation of the seat, so that a seat is initialized only the
peer really do the activation sequence. That helps when mstsc just connects to see
the certificate, ask if the certificate should be trusted, and then reconnects.

This patch also adds configuration settings for recent versions of FreeRDP that
comes with everything disabled. This makes remoteFx functionnal again.

The patch also handles the skipCompression flag for last FreeRDP versions, that
allows to skip bulk compression for surfaces that have been already compressed by
the remoteFx or NS codec.

This also fixes the compilation against FreeRDP master with callback that now return
BOOL.

Signed-off-by: Hardening <rdp.effort@gmail.com>
Acked-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
dev
Hardening 10 years ago committed by David FORT
parent e4df9eea26
commit 0c944b07c4
  1. 127
      src/compositor-rdp.c

@ -33,6 +33,23 @@
/* assume it's a early 1.1 version */ /* assume it's a early 1.1 version */
#define FREERDP_VERSION_MAJOR 1 #define FREERDP_VERSION_MAJOR 1
#define FREERDP_VERSION_MINOR 1 #define FREERDP_VERSION_MINOR 1
#define FREERDP_VERSION_REVISION 0
#endif
#define FREERDP_VERSION_NUMBER ((FREERDP_VERSION_MAJOR * 0x10000) + \
(FREERDP_VERSION_MINOR * 0x100) + FREERDP_VERSION_REVISION)
#if FREERDP_VERSION_NUMBER >= 0x10201
#define HAVE_SKIP_COMPRESSION
#endif
#if FREERDP_VERSION_NUMBER < 0x10202
#define FREERDP_CB_RET_TYPE void
#define FREERDP_CB_RETURN(V) return
#else
#define HAVE_NSC_RESET
#define FREERDP_CB_RET_TYPE BOOL
#define FREERDP_CB_RETURN(V) return TRUE
#endif #endif
#include <freerdp/freerdp.h> #include <freerdp/freerdp.h>
@ -145,6 +162,11 @@ rdp_peer_refresh_rfx(pixman_region32_t *damage, pixman_image_t *image, freerdp_p
width = (damage->extents.x2 - damage->extents.x1); width = (damage->extents.x2 - damage->extents.x1);
height = (damage->extents.y2 - damage->extents.y1); height = (damage->extents.y2 - damage->extents.y1);
#ifdef HAVE_SKIP_COMPRESSION
cmd->skipCompression = TRUE;
#else
memset(cmd, 0, sizeof(*cmd));
#endif
cmd->destLeft = damage->extents.x1; cmd->destLeft = damage->extents.x1;
cmd->destTop = damage->extents.y1; cmd->destTop = damage->extents.y1;
cmd->destRight = damage->extents.x2; cmd->destRight = damage->extents.x2;
@ -197,6 +219,11 @@ rdp_peer_refresh_nsc(pixman_region32_t *damage, pixman_image_t *image, freerdp_p
width = (damage->extents.x2 - damage->extents.x1); width = (damage->extents.x2 - damage->extents.x1);
height = (damage->extents.y2 - damage->extents.y1); height = (damage->extents.y2 - damage->extents.y1);
#ifdef HAVE_SKIP_COMPRESSION
cmd->skipCompression = TRUE;
#else
memset(cmd, 0, sizeof(*cmd));
#endif
cmd->destLeft = damage->extents.x1; cmd->destLeft = damage->extents.x1;
cmd->destTop = damage->extents.y1; cmd->destTop = damage->extents.y1;
cmd->destRight = damage->extents.x2; cmd->destRight = damage->extents.x2;
@ -248,6 +275,7 @@ rdp_peer_refresh_raw(pixman_region32_t *region, pixman_image_t *image, freerdp_p
marker->frameAction = SURFACECMD_FRAMEACTION_BEGIN; marker->frameAction = SURFACECMD_FRAMEACTION_BEGIN;
update->SurfaceFrameMarker(peer->context, marker); update->SurfaceFrameMarker(peer->context, marker);
memset(cmd, 0, sizeof(*cmd));
cmd->bpp = 32; cmd->bpp = 32;
cmd->codecID = 0; cmd->codecID = 0;
@ -592,6 +620,7 @@ rdp_peer_context_free(freerdp_peer* client, RdpPeerContext* context)
weston_seat_release_pointer(&context->item.seat); weston_seat_release_pointer(&context->item.seat);
weston_seat_release(&context->item.seat); weston_seat_release(&context->item.seat);
} }
Stream_Free(context->encode_stream, TRUE); Stream_Free(context->encode_stream, TRUE);
nsc_context_free(context->nsc_context); nsc_context_free(context->nsc_context);
rfx_context_free(context->rfx_context); rfx_context_free(context->rfx_context);
@ -757,23 +786,26 @@ static char *rdp_keyboard_types[] = {
}; };
static BOOL static BOOL
xf_peer_post_connect(freerdp_peer* client) xf_peer_activate(freerdp_peer* client)
{ {
RdpPeerContext *peerCtx; RdpPeerContext *peerCtx;
struct rdp_compositor *c; struct rdp_compositor *c;
struct rdp_output *output; struct rdp_output *output;
rdpSettings *settings; rdpSettings *settings;
rdpPointerUpdate *pointer; rdpPointerUpdate *pointer;
struct rdp_peers_item *peersItem;
struct xkb_context *xkbContext; struct xkb_context *xkbContext;
struct xkb_rule_names xkbRuleNames; struct xkb_rule_names xkbRuleNames;
struct xkb_keymap *keymap; struct xkb_keymap *keymap;
int i; int i;
pixman_box32_t box; pixman_box32_t box;
pixman_region32_t damage; pixman_region32_t damage;
char seat_name[50];
peerCtx = (RdpPeerContext *)client->context; peerCtx = (RdpPeerContext *)client->context;
c = peerCtx->rdpCompositor; c = peerCtx->rdpCompositor;
peersItem = &peerCtx->item;
output = c->output; output = c->output;
settings = client->settings; settings = client->settings;
@ -813,7 +845,16 @@ xf_peer_post_connect(freerdp_peer* client)
} }
} }
weston_log("kbd_layout:%x kbd_type:%x kbd_subType:%x kbd_functionKeys:%x\n", rfx_context_reset(peerCtx->rfx_context);
#ifdef HAVE_NSC_RESET
nsc_context_reset(peerCtx->nsc_context);
#endif
if (peersItem->flags & RDP_PEER_ACTIVATED)
return TRUE;
/* when here it's the first reactivation, we need to setup a little more */
weston_log("kbd_layout:0x%x kbd_type:0x%x kbd_subType:0x%x kbd_functionKeys:0x%x\n",
settings->KeyboardLayout, settings->KeyboardType, settings->KeyboardSubType, settings->KeyboardLayout, settings->KeyboardType, settings->KeyboardSubType,
settings->KeyboardFunctionKey); settings->KeyboardFunctionKey);
@ -840,10 +881,17 @@ xf_peer_post_connect(freerdp_peer* client)
keymap = xkb_keymap_new_from_names(xkbContext, &xkbRuleNames, 0); keymap = xkb_keymap_new_from_names(xkbContext, &xkbRuleNames, 0);
} }
weston_seat_init_keyboard(&peerCtx->item.seat, keymap);
weston_seat_init_pointer(&peerCtx->item.seat);
peerCtx->item.flags |= RDP_PEER_ACTIVATED; if (settings->ClientHostname)
snprintf(seat_name, sizeof(seat_name), "RDP %s", settings->ClientHostname);
else
snprintf(seat_name, sizeof(seat_name), "RDP peer @%s", settings->ClientAddress);
weston_seat_init(&peersItem->seat, &c->base, seat_name);
weston_seat_init_keyboard(&peersItem->seat, keymap);
weston_seat_init_pointer(&peersItem->seat);
peersItem->flags |= RDP_PEER_ACTIVATED;
/* disable pointer on the client side */ /* disable pointer on the client side */
pointer = client->update->pointer; pointer = client->update->pointer;
@ -864,15 +912,12 @@ xf_peer_post_connect(freerdp_peer* client)
return TRUE; return TRUE;
} }
static BOOL static BOOL xf_peer_post_connect(freerdp_peer *client)
xf_peer_activate(freerdp_peer *client)
{ {
RdpPeerContext *context = (RdpPeerContext *)client->context;
rfx_context_reset(context->rfx_context);
return TRUE; return TRUE;
} }
static void static FREERDP_CB_RET_TYPE
xf_mouseEvent(rdpInput *input, UINT16 flags, UINT16 x, UINT16 y) { xf_mouseEvent(rdpInput *input, UINT16 flags, UINT16 x, UINT16 y) {
wl_fixed_t wl_x, wl_y, axis; wl_fixed_t wl_x, wl_y, axis;
RdpPeerContext *peerContext = (RdpPeerContext *)input->context; RdpPeerContext *peerContext = (RdpPeerContext *)input->context;
@ -917,9 +962,11 @@ xf_mouseEvent(rdpInput *input, UINT16 flags, UINT16 x, UINT16 y) {
WL_POINTER_AXIS_VERTICAL_SCROLL, WL_POINTER_AXIS_VERTICAL_SCROLL,
axis); axis);
} }
FREERDP_CB_RETURN(TRUE);
} }
static void static FREERDP_CB_RET_TYPE
xf_extendedMouseEvent(rdpInput *input, UINT16 flags, UINT16 x, UINT16 y) { xf_extendedMouseEvent(rdpInput *input, UINT16 flags, UINT16 x, UINT16 y) {
wl_fixed_t wl_x, wl_y; wl_fixed_t wl_x, wl_y;
RdpPeerContext *peerContext = (RdpPeerContext *)input->context; RdpPeerContext *peerContext = (RdpPeerContext *)input->context;
@ -932,10 +979,12 @@ xf_extendedMouseEvent(rdpInput *input, UINT16 flags, UINT16 x, UINT16 y) {
notify_motion_absolute(&peerContext->item.seat, weston_compositor_get_time(), notify_motion_absolute(&peerContext->item.seat, weston_compositor_get_time(),
wl_x, wl_y); wl_x, wl_y);
} }
FREERDP_CB_RETURN(TRUE);
} }
static void static FREERDP_CB_RET_TYPE
xf_input_synchronize_event(rdpInput *input, UINT32 flags) xf_input_synchronize_event(rdpInput *input, UINT32 flags)
{ {
freerdp_peer *client = input->context->peer; freerdp_peer *client = input->context->peer;
@ -954,10 +1003,11 @@ xf_input_synchronize_event(rdpInput *input, UINT32 flags)
rdp_peer_refresh_region(&damage, client); rdp_peer_refresh_region(&damage, client);
pixman_region32_fini(&damage); pixman_region32_fini(&damage);
FREERDP_CB_RETURN(TRUE);
} }
static void static FREERDP_CB_RET_TYPE
xf_input_keyboard_event(rdpInput *input, UINT16 flags, UINT16 code) xf_input_keyboard_event(rdpInput *input, UINT16 flags, UINT16 code)
{ {
uint32_t scan_code, vk_code, full_code; uint32_t scan_code, vk_code, full_code;
@ -965,6 +1015,9 @@ xf_input_keyboard_event(rdpInput *input, UINT16 flags, UINT16 code)
RdpPeerContext *peerContext = (RdpPeerContext *)input->context; RdpPeerContext *peerContext = (RdpPeerContext *)input->context;
int notify = 0; int notify = 0;
if (!(peerContext->item.flags & RDP_PEER_ACTIVATED))
FREERDP_CB_RETURN(TRUE);
if (flags & KBD_FLAGS_DOWN) { if (flags & KBD_FLAGS_DOWN) {
keyState = WL_KEYBOARD_KEY_STATE_PRESSED; keyState = WL_KEYBOARD_KEY_STATE_PRESSED;
notify = 1; notify = 1;
@ -989,22 +1042,28 @@ xf_input_keyboard_event(rdpInput *input, UINT16 flags, UINT16 code)
notify_key(&peerContext->item.seat, weston_compositor_get_time(), notify_key(&peerContext->item.seat, weston_compositor_get_time(),
scan_code - 8, keyState, STATE_UPDATE_AUTOMATIC); scan_code - 8, keyState, STATE_UPDATE_AUTOMATIC);
} }
FREERDP_CB_RETURN(TRUE);
} }
static void static FREERDP_CB_RET_TYPE
xf_input_unicode_keyboard_event(rdpInput *input, UINT16 flags, UINT16 code) xf_input_unicode_keyboard_event(rdpInput *input, UINT16 flags, UINT16 code)
{ {
weston_log("Client sent a unicode keyboard event (flags:0x%X code:0x%X)\n", flags, code); weston_log("Client sent a unicode keyboard event (flags:0x%X code:0x%X)\n", flags, code);
FREERDP_CB_RETURN(TRUE);
} }
static void static FREERDP_CB_RET_TYPE
xf_suppress_output(rdpContext *context, BYTE allow, RECTANGLE_16 *area) { xf_suppress_output(rdpContext *context, BYTE allow, RECTANGLE_16 *area) {
RdpPeerContext *peerContext = (RdpPeerContext *)context; RdpPeerContext *peerContext = (RdpPeerContext *)context;
if (allow) if (allow)
peerContext->item.flags |= RDP_PEER_OUTPUT_ENABLED; peerContext->item.flags |= RDP_PEER_OUTPUT_ENABLED;
else else
peerContext->item.flags &= (~RDP_PEER_OUTPUT_ENABLED); peerContext->item.flags &= (~RDP_PEER_OUTPUT_ENABLED);
FREERDP_CB_RETURN(TRUE);
} }
static int static int
@ -1017,7 +1076,6 @@ rdp_peer_init(freerdp_peer *client, struct rdp_compositor *c)
rdpSettings *settings; rdpSettings *settings;
rdpInput *input; rdpInput *input;
RdpPeerContext *peerCtx; RdpPeerContext *peerCtx;
char seat_name[32];
client->ContextSize = sizeof(RdpPeerContext); client->ContextSize = sizeof(RdpPeerContext);
client->ContextNew = (psPeerContextNew)rdp_peer_context_new; client->ContextNew = (psPeerContextNew)rdp_peer_context_new;
@ -1027,17 +1085,29 @@ rdp_peer_init(freerdp_peer *client, struct rdp_compositor *c)
peerCtx = (RdpPeerContext *) client->context; peerCtx = (RdpPeerContext *) client->context;
peerCtx->rdpCompositor = c; peerCtx->rdpCompositor = c;
client->Initialize(client);
settings = client->settings; settings = client->settings;
settings->RdpKeyFile = c->rdp_key; /* configure security settings */
if (c->rdp_key)
settings->RdpKeyFile = strdup(c->rdp_key);
if (c->tls_enabled) { if (c->tls_enabled) {
settings->CertificateFile = c->server_cert; settings->CertificateFile = strdup( c->server_cert);
settings->PrivateKeyFile = c->server_key; settings->PrivateKeyFile = strdup(c->server_key);
} else { } else {
settings->TlsSecurity = FALSE; settings->TlsSecurity = FALSE;
} }
settings->NlaSecurity = FALSE; settings->NlaSecurity = FALSE;
settings->OsMajorType = OSMAJORTYPE_UNIX;
settings->OsMinorType = OSMINORTYPE_PSEUDO_XSERVER;
settings->ColorDepth = 32;
settings->RefreshRect = TRUE;
settings->RemoteFxCodec = TRUE;
settings->NSCodec = TRUE;
settings->FrameMarkerCommandEnabled = TRUE;
settings->SurfaceFrameMarkerEnabled = TRUE;
client->Capabilities = xf_peer_capabilities; client->Capabilities = xf_peer_capabilities;
client->PostConnect = xf_peer_post_connect; client->PostConnect = xf_peer_post_connect;
client->Activate = xf_peer_activate; client->Activate = xf_peer_activate;
@ -1051,13 +1121,6 @@ rdp_peer_init(freerdp_peer *client, struct rdp_compositor *c)
input->KeyboardEvent = xf_input_keyboard_event; input->KeyboardEvent = xf_input_keyboard_event;
input->UnicodeKeyboardEvent = xf_input_unicode_keyboard_event; input->UnicodeKeyboardEvent = xf_input_unicode_keyboard_event;
if (snprintf(seat_name, 32, "rdp:%d:%s", client->sockfd, client->hostname) >= 32)
seat_name[31] = '\0';
weston_seat_init(&peerCtx->item.seat, &c->base, seat_name);
client->Initialize(client);
if (!client->GetFileDescriptor(client, rfds, &rcount)) { if (!client->GetFileDescriptor(client, rfds, &rcount)) {
weston_log("unable to retrieve client fds\n"); weston_log("unable to retrieve client fds\n");
return -1; return -1;
@ -1078,12 +1141,16 @@ rdp_peer_init(freerdp_peer *client, struct rdp_compositor *c)
} }
static void static FREERDP_CB_RET_TYPE
rdp_incoming_peer(freerdp_listener *instance, freerdp_peer *client) rdp_incoming_peer(freerdp_listener *instance, freerdp_peer *client)
{ {
struct rdp_compositor *c = (struct rdp_compositor *)instance->param4; struct rdp_compositor *c = (struct rdp_compositor *)instance->param4;
if (rdp_peer_init(client, c) < 0) if (rdp_peer_init(client, c) < 0) {
return; weston_log("error when treating incoming peer");
FREERDP_CB_RETURN(FALSE);
}
FREERDP_CB_RETURN(TRUE);
} }
static struct weston_compositor * static struct weston_compositor *

Loading…
Cancel
Save