rdp: Allow specifying a listener fd on the command line
We already have a way for a single RDP client connection to be passed from a parent process to a child using a combination of environment variable (RDP_FD) and env var (--env-socket) This patch allows a bound socket fd (as opposed to a client connection) to be established in a parent process and provided to the rdp backend. WSLg uses this to set up an AF_VSOCK socket for communication between a Windows RDP client and a weston compositor running under a hypervisor. Co-authored-by: Hideyuki Nagase <hideyukn@microsoft.com> Co-authored-by: Steve Pronovost <spronovo@microsoft.com> Signed-off-by: Hideyuki Nagase <hideyukn@microsoft.com> Signed-off-by: Steve Pronovost <spronovo@microsoft.com> Signed-off-by: Brenton DeGeer <brdegeer@microsoft.com>
This commit is contained in:
committed by
Derek Foreman
parent
13e62c9d18
commit
2f9319cef6
@@ -688,6 +688,7 @@ usage(int error_code)
|
|||||||
" --width=WIDTH\t\tWidth of desktop\n"
|
" --width=WIDTH\t\tWidth of desktop\n"
|
||||||
" --height=HEIGHT\tHeight of desktop\n"
|
" --height=HEIGHT\tHeight of desktop\n"
|
||||||
" --env-socket\t\tUse socket defined in RDP_FD env variable as peer connection\n"
|
" --env-socket\t\tUse socket defined in RDP_FD env variable as peer connection\n"
|
||||||
|
" --external-listener-fd=FD\tUse socket as listener connection\n"
|
||||||
" --address=ADDR\tThe address to bind\n"
|
" --address=ADDR\tThe address to bind\n"
|
||||||
" --port=PORT\t\tThe port to listen on\n"
|
" --port=PORT\t\tThe port to listen on\n"
|
||||||
" --no-clients-resize\tThe RDP peers will be forced to the size of the desktop\n"
|
" --no-clients-resize\tThe RDP peers will be forced to the size of the desktop\n"
|
||||||
@@ -2772,6 +2773,7 @@ weston_rdp_backend_config_init(struct weston_rdp_backend_config *config)
|
|||||||
config->server_cert = NULL;
|
config->server_cert = NULL;
|
||||||
config->server_key = NULL;
|
config->server_key = NULL;
|
||||||
config->env_socket = 0;
|
config->env_socket = 0;
|
||||||
|
config->external_listener_fd = -1;
|
||||||
config->no_clients_resize = 0;
|
config->no_clients_resize = 0;
|
||||||
config->force_no_compression = 0;
|
config->force_no_compression = 0;
|
||||||
config->remotefx_codec = true;
|
config->remotefx_codec = true;
|
||||||
@@ -2793,6 +2795,7 @@ load_rdp_backend(struct weston_compositor *c,
|
|||||||
|
|
||||||
const struct weston_option rdp_options[] = {
|
const struct weston_option rdp_options[] = {
|
||||||
{ WESTON_OPTION_BOOLEAN, "env-socket", 0, &config.env_socket },
|
{ WESTON_OPTION_BOOLEAN, "env-socket", 0, &config.env_socket },
|
||||||
|
{ WESTON_OPTION_INTEGER, "external-listener-fd", 0, &config.external_listener_fd },
|
||||||
{ WESTON_OPTION_INTEGER, "width", 0, &parsed_options->width },
|
{ WESTON_OPTION_INTEGER, "width", 0, &parsed_options->width },
|
||||||
{ WESTON_OPTION_INTEGER, "height", 0, &parsed_options->height },
|
{ WESTON_OPTION_INTEGER, "height", 0, &parsed_options->height },
|
||||||
{ WESTON_OPTION_STRING, "address", 0, &config.bind_address },
|
{ WESTON_OPTION_STRING, "address", 0, &config.bind_address },
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ struct weston_rdp_backend_config {
|
|||||||
int no_clients_resize;
|
int no_clients_resize;
|
||||||
int force_no_compression;
|
int force_no_compression;
|
||||||
bool remotefx_codec;
|
bool remotefx_codec;
|
||||||
|
int external_listener_fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
+29
-12
@@ -1354,14 +1354,27 @@ rdp_backend_create(struct weston_compositor *compositor,
|
|||||||
|
|
||||||
compositor->backend = &b->base;
|
compositor->backend = &b->base;
|
||||||
|
|
||||||
/* activate TLS only if certificate/key are available */
|
|
||||||
if (config->server_cert && config->server_key) {
|
if (config->server_cert && config->server_key) {
|
||||||
weston_log("TLS support activated\n");
|
|
||||||
b->server_cert = strdup(config->server_cert);
|
b->server_cert = strdup(config->server_cert);
|
||||||
b->server_key = strdup(config->server_key);
|
b->server_key = strdup(config->server_key);
|
||||||
if (!b->server_cert || !b->server_key)
|
if (!b->server_cert || !b->server_key)
|
||||||
goto err_free_strings;
|
goto err_free_strings;
|
||||||
b->tls_enabled = 1;
|
}
|
||||||
|
|
||||||
|
/* if we are listening for client connections on an external listener
|
||||||
|
* fd, we don't need to enforce TLS or RDP security, since FreeRDP
|
||||||
|
* will consider it to be a local connection */
|
||||||
|
fd = config->external_listener_fd;
|
||||||
|
if (fd < 0) {
|
||||||
|
if (!b->rdp_key && (!b->server_cert || !b->server_key)) {
|
||||||
|
weston_log("the RDP compositor requires keys and an optional certificate for RDP or TLS security ("
|
||||||
|
"--rdp4-key or --rdp-tls-cert/--rdp-tls-key)\n");
|
||||||
|
goto err_free_strings;
|
||||||
|
}
|
||||||
|
if (b->server_cert && b->server_key) {
|
||||||
|
b->tls_enabled = 1;
|
||||||
|
rdp_debug(b, "TLS support activated\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (weston_compositor_set_presentation_clock_software(compositor) < 0)
|
if (weston_compositor_set_presentation_clock_software(compositor) < 0)
|
||||||
@@ -1379,9 +1392,18 @@ rdp_backend_create(struct weston_compositor *compositor,
|
|||||||
b->listener = freerdp_listener_new();
|
b->listener = freerdp_listener_new();
|
||||||
b->listener->PeerAccepted = rdp_incoming_peer;
|
b->listener->PeerAccepted = rdp_incoming_peer;
|
||||||
b->listener->param4 = b;
|
b->listener->param4 = b;
|
||||||
if (!b->listener->Open(b->listener, config->bind_address, config->port)) {
|
if (fd >= 0) {
|
||||||
weston_log("unable to bind rdp socket\n");
|
rdp_debug(b, "Using external fd for incoming connections: %d\n", fd);
|
||||||
goto err_listener;
|
|
||||||
|
if (!b->listener->OpenFromSocket(b->listener, fd)) {
|
||||||
|
weston_log("RDP unable to use external listener fd: %d\n", fd);
|
||||||
|
goto err_listener;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!b->listener->Open(b->listener, config->bind_address, config->port)) {
|
||||||
|
weston_log("RDP unable to bind socket\n");
|
||||||
|
goto err_listener;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rdp_implant_listener(b, b->listener) < 0)
|
if (rdp_implant_listener(b, b->listener) < 0)
|
||||||
@@ -1444,6 +1466,7 @@ config_init_to_defaults(struct weston_rdp_backend_config *config)
|
|||||||
config->no_clients_resize = 0;
|
config->no_clients_resize = 0;
|
||||||
config->force_no_compression = 0;
|
config->force_no_compression = 0;
|
||||||
config->remotefx_codec = true;
|
config->remotefx_codec = true;
|
||||||
|
config->external_listener_fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
WL_EXPORT int
|
WL_EXPORT int
|
||||||
@@ -1470,12 +1493,6 @@ weston_backend_init(struct weston_compositor *compositor,
|
|||||||
config_init_to_defaults(&config);
|
config_init_to_defaults(&config);
|
||||||
memcpy(&config, config_base, config_base->struct_size);
|
memcpy(&config, config_base, config_base->struct_size);
|
||||||
|
|
||||||
if (!config.rdp_key && (!config.server_cert || !config.server_key)) {
|
|
||||||
weston_log("the RDP compositor requires keys and an optional certificate for RDP or TLS security ("
|
|
||||||
"--rdp4-key or --rdp-tls-cert/--rdp-tls-key)\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
b = rdp_backend_create(compositor, &config);
|
b = rdp_backend_create(compositor, &config);
|
||||||
if (b == NULL)
|
if (b == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ struct rdp_backend {
|
|||||||
int no_clients_resize;
|
int no_clients_resize;
|
||||||
int force_no_compression;
|
int force_no_compression;
|
||||||
bool remotefx_codec;
|
bool remotefx_codec;
|
||||||
|
int external_listener_fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum peer_item_flags {
|
enum peer_item_flags {
|
||||||
|
|||||||
@@ -59,6 +59,12 @@ to ship a file containing a certificate.
|
|||||||
\fB\-\-rdp\-tls\-cert\fR=\fIfile\fR
|
\fB\-\-rdp\-tls\-cert\fR=\fIfile\fR
|
||||||
The file containing the certificate for doing TLS security. To have TLS security you also need
|
The file containing the certificate for doing TLS security. To have TLS security you also need
|
||||||
to ship a key file.
|
to ship a key file.
|
||||||
|
.TP
|
||||||
|
\fB\-\-external\-listener\-fd\fR=\fIfd\fR
|
||||||
|
Specifies a file descriptor inherited from the process that launched weston
|
||||||
|
to be listened on for client connections. Only local (such as AF_VSOCK)
|
||||||
|
sockets should be used, as this will be considered to be a local connection
|
||||||
|
by the RDP backend, and TLS and RDP security will be bypassed.
|
||||||
|
|
||||||
|
|
||||||
.\" ***************************************************************
|
.\" ***************************************************************
|
||||||
|
|||||||
Reference in New Issue
Block a user