From 2f9319cef611a1c2925e65d63e1068b8f80a531b Mon Sep 17 00:00:00 2001 From: Brenton DeGeer Date: Tue, 15 Mar 2022 12:24:42 -0500 Subject: [PATCH] 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 Co-authored-by: Steve Pronovost Signed-off-by: Hideyuki Nagase Signed-off-by: Steve Pronovost Signed-off-by: Brenton DeGeer --- compositor/main.c | 3 +++ include/libweston/backend-rdp.h | 1 + libweston/backend-rdp/rdp.c | 41 +++++++++++++++++++++++---------- libweston/backend-rdp/rdp.h | 1 + man/weston-rdp.man | 6 +++++ 5 files changed, 40 insertions(+), 12 deletions(-) diff --git a/compositor/main.c b/compositor/main.c index dfc3d4bd..7bfcbc2d 100644 --- a/compositor/main.c +++ b/compositor/main.c @@ -688,6 +688,7 @@ usage(int error_code) " --width=WIDTH\t\tWidth of desktop\n" " --height=HEIGHT\tHeight of desktop\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" " --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" @@ -2772,6 +2773,7 @@ weston_rdp_backend_config_init(struct weston_rdp_backend_config *config) config->server_cert = NULL; config->server_key = NULL; config->env_socket = 0; + config->external_listener_fd = -1; config->no_clients_resize = 0; config->force_no_compression = 0; config->remotefx_codec = true; @@ -2793,6 +2795,7 @@ load_rdp_backend(struct weston_compositor *c, const struct weston_option rdp_options[] = { { 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, "height", 0, &parsed_options->height }, { WESTON_OPTION_STRING, "address", 0, &config.bind_address }, diff --git a/include/libweston/backend-rdp.h b/include/libweston/backend-rdp.h index 2c55818b..d9f56b93 100644 --- a/include/libweston/backend-rdp.h +++ b/include/libweston/backend-rdp.h @@ -67,6 +67,7 @@ struct weston_rdp_backend_config { int no_clients_resize; int force_no_compression; bool remotefx_codec; + int external_listener_fd; }; #ifdef __cplusplus diff --git a/libweston/backend-rdp/rdp.c b/libweston/backend-rdp/rdp.c index a7fb59c3..97d0244f 100644 --- a/libweston/backend-rdp/rdp.c +++ b/libweston/backend-rdp/rdp.c @@ -1354,14 +1354,27 @@ rdp_backend_create(struct weston_compositor *compositor, compositor->backend = &b->base; - /* activate TLS only if certificate/key are available */ if (config->server_cert && config->server_key) { - weston_log("TLS support activated\n"); b->server_cert = strdup(config->server_cert); b->server_key = strdup(config->server_key); if (!b->server_cert || !b->server_key) 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) @@ -1379,9 +1392,18 @@ rdp_backend_create(struct weston_compositor *compositor, b->listener = freerdp_listener_new(); b->listener->PeerAccepted = rdp_incoming_peer; b->listener->param4 = b; - if (!b->listener->Open(b->listener, config->bind_address, config->port)) { - weston_log("unable to bind rdp socket\n"); - goto err_listener; + if (fd >= 0) { + rdp_debug(b, "Using external fd for incoming connections: %d\n", fd); + + 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) @@ -1444,6 +1466,7 @@ config_init_to_defaults(struct weston_rdp_backend_config *config) config->no_clients_resize = 0; config->force_no_compression = 0; config->remotefx_codec = true; + config->external_listener_fd = -1; } WL_EXPORT int @@ -1470,12 +1493,6 @@ weston_backend_init(struct weston_compositor *compositor, config_init_to_defaults(&config); 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); if (b == NULL) return -1; diff --git a/libweston/backend-rdp/rdp.h b/libweston/backend-rdp/rdp.h index 31e56d96..e25082b6 100644 --- a/libweston/backend-rdp/rdp.h +++ b/libweston/backend-rdp/rdp.h @@ -71,6 +71,7 @@ struct rdp_backend { int no_clients_resize; int force_no_compression; bool remotefx_codec; + int external_listener_fd; }; enum peer_item_flags { diff --git a/man/weston-rdp.man b/man/weston-rdp.man index 1d6ccfd0..8900a6ca 100644 --- a/man/weston-rdp.man +++ b/man/weston-rdp.man @@ -59,6 +59,12 @@ to ship a file containing a certificate. \fB\-\-rdp\-tls\-cert\fR=\fIfile\fR The file containing the certificate for doing TLS security. To have TLS security you also need 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. .\" ***************************************************************