From 8da900636f7e0aab4fc81019832dfd7e60aab74b Mon Sep 17 00:00:00 2001 From: eabdullin Date: Thu, 10 Jul 2025 06:35:25 +0000 Subject: [PATCH] import CS gnome-remote-desktop-47.3-2.el10 --- .gitignore | 2 +- .gnome-remote-desktop.metadata | 1 - .../0001-stream-log-a-warning-on-error.patch | 52 -- ...pewire-stream-Handle-stride-mismatch.patch | 73 -- ...01-vnc-pipewire-stream-Remove-assert.patch | 25 - ...eam-Only-try-to-copy-frame-pixels-if.patch | 62 -- SOURCES/cursor-only-frame-fixes.patch | 127 --- SPECS/gnome-remote-desktop.spec | 148 ---- ...tling.patch => connection-throttling.patch | 805 +++++++++++++----- gnome-remote-desktop.spec | 392 +++++++++ ...-tls-support.patch => gnutls-anontls.patch | 486 +++++------ sources | 1 + 12 files changed, 1220 insertions(+), 954 deletions(-) delete mode 100644 .gnome-remote-desktop.metadata delete mode 100644 SOURCES/0001-stream-log-a-warning-on-error.patch delete mode 100644 SOURCES/0001-vnc-pipewire-stream-Handle-stride-mismatch.patch delete mode 100644 SOURCES/0001-vnc-pipewire-stream-Remove-assert.patch delete mode 100644 SOURCES/0002-vnc-pipewire-stream-Only-try-to-copy-frame-pixels-if.patch delete mode 100644 SOURCES/cursor-only-frame-fixes.patch delete mode 100644 SPECS/gnome-remote-desktop.spec rename SOURCES/connection-throttling.patch => connection-throttling.patch (62%) create mode 100644 gnome-remote-desktop.spec rename SOURCES/anon-tls-support.patch => gnutls-anontls.patch (78%) create mode 100644 sources diff --git a/.gitignore b/.gitignore index b4469da..19ad0ec 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/gnome-remote-desktop-0.1.8.tar.xz +gnome-remote-desktop-47.3.tar.xz diff --git a/.gnome-remote-desktop.metadata b/.gnome-remote-desktop.metadata deleted file mode 100644 index e2dae6d..0000000 --- a/.gnome-remote-desktop.metadata +++ /dev/null @@ -1 +0,0 @@ -3347257bd906cd0ca86887c692befd8d412afab1 SOURCES/gnome-remote-desktop-0.1.8.tar.xz diff --git a/SOURCES/0001-stream-log-a-warning-on-error.patch b/SOURCES/0001-stream-log-a-warning-on-error.patch deleted file mode 100644 index a8b005e..0000000 --- a/SOURCES/0001-stream-log-a-warning-on-error.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 7670167e578eb5c6e032cff38112edf85df142ee Mon Sep 17 00:00:00 2001 -From: Wim Taymans -Date: Tue, 16 Jun 2020 11:44:52 +0200 -Subject: [PATCH 1/2] stream: log a warning on error - -When we get an invalid buffer or we can't mmap() it, log a warning -and exit instead of carying on with invalid pointers and segfault. ---- - src/grd-vnc-pipewire-stream.c | 15 ++++++++++++--- - 1 file changed, 12 insertions(+), 3 deletions(-) - -diff --git a/src/grd-vnc-pipewire-stream.c b/src/grd-vnc-pipewire-stream.c -index 261292a..91fb0a1 100644 ---- a/src/grd-vnc-pipewire-stream.c -+++ b/src/grd-vnc-pipewire-stream.c -@@ -323,14 +323,18 @@ process_buffer (GrdVncPipeWireStream *stream, - - if (buffer->datas[0].chunk->size == 0) - { -- size = 0; -- map = NULL; -- src_data = NULL; -+ g_warning ("Received empty buffer"); -+ return NULL; - } - else if (buffer->datas[0].type == SPA_DATA_MemFd) - { - size = buffer->datas[0].maxsize + buffer->datas[0].mapoffset; - map = mmap (NULL, size, PROT_READ, MAP_PRIVATE, buffer->datas[0].fd, 0); -+ if (map == MAP_FAILED) -+ { -+ g_warning ("Failed to mmap buffer: %s", g_strerror (errno)); -+ return NULL; -+ } - src_data = SPA_MEMBER (map, buffer->datas[0].mapoffset, uint8_t); - } - else if (buffer->datas[0].type == SPA_DATA_DmaBuf) -@@ -341,6 +345,11 @@ process_buffer (GrdVncPipeWireStream *stream, - size = buffer->datas[0].maxsize + buffer->datas[0].mapoffset; - - map = mmap (NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); -+ if (map == MAP_FAILED) -+ { -+ g_warning ("Failed to mmap DMA buffer: %s", g_strerror (errno)); -+ return NULL; -+ } - sync_dma_buf (fd, DMA_BUF_SYNC_START); - - src_data = SPA_MEMBER (map, buffer->datas[0].mapoffset, uint8_t); --- -2.26.2 - diff --git a/SOURCES/0001-vnc-pipewire-stream-Handle-stride-mismatch.patch b/SOURCES/0001-vnc-pipewire-stream-Handle-stride-mismatch.patch deleted file mode 100644 index 59bc460..0000000 --- a/SOURCES/0001-vnc-pipewire-stream-Handle-stride-mismatch.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 78c5bcb181fe2b0b9fc17eea696feac8b504df54 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jonas=20=C3=85dahl?= -Date: Thu, 7 May 2020 15:48:22 +0200 -Subject: [PATCH] vnc/pipewire-stream: Handle stride mismatch - -The VNC server framebuffer assumes a particular stride; but there is no -guarantee that we'll get the same from PipeWire. Handle this gracefully -by coping row by row instead of the whole buffer. ---- - src/grd-vnc-pipewire-stream.c | 23 +++++++++++++++-------- - 1 file changed, 15 insertions(+), 8 deletions(-) - -diff --git a/src/grd-vnc-pipewire-stream.c b/src/grd-vnc-pipewire-stream.c -index 88c07be..261292a 100644 ---- a/src/grd-vnc-pipewire-stream.c -+++ b/src/grd-vnc-pipewire-stream.c -@@ -187,8 +187,6 @@ on_stream_param_changed (void *user_data, - struct spa_pod_builder pod_builder; - int width; - int height; -- int stride; -- int size; - const struct spa_pod *params[3]; - - if (!format || id != SPA_PARAM_Format) -@@ -203,14 +201,9 @@ on_stream_param_changed (void *user_data, - - grd_session_vnc_queue_resize_framebuffer (stream->session, width, height); - -- stride = grd_session_vnc_get_framebuffer_stride (stream->session); -- size = stride * height; -- - params[0] = spa_pod_builder_add_object ( - &pod_builder, - SPA_TYPE_OBJECT_ParamBuffers, SPA_PARAM_Buffers, -- SPA_PARAM_BUFFERS_size, SPA_POD_Int (size), -- SPA_PARAM_BUFFERS_stride, SPA_POD_Int (stride), - SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int (8, 1, 8), - 0); - -@@ -319,6 +312,10 @@ process_buffer (GrdVncPipeWireStream *stream, - size_t size; - uint8_t *map; - void *src_data; -+ int src_stride; -+ int dst_stride; -+ int height; -+ int y; - struct spa_meta_cursor *spa_meta_cursor; - g_autofree GrdVncFrame *frame = NULL; - -@@ -359,7 +356,17 @@ process_buffer (GrdVncPipeWireStream *stream, - return NULL; - } - -- frame->data = g_memdup (src_data, buffer->datas[0].maxsize); -+ src_stride = buffer->datas[0].chunk->stride; -+ dst_stride = grd_session_vnc_get_framebuffer_stride (stream->session); -+ height = stream->spa_format.size.height; -+ -+ frame->data = g_malloc (height * dst_stride); -+ for (y = 0; y < height; y++) -+ { -+ memcpy (((uint8_t *) frame->data) + y * dst_stride, -+ ((uint8_t *) src_data) + y * src_stride, -+ dst_stride); -+ } - - if (map) - { --- -2.26.2 - diff --git a/SOURCES/0001-vnc-pipewire-stream-Remove-assert.patch b/SOURCES/0001-vnc-pipewire-stream-Remove-assert.patch deleted file mode 100644 index 69e71b7..0000000 --- a/SOURCES/0001-vnc-pipewire-stream-Remove-assert.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 240d8694fbcdeb020e7f9c0f8f292a4679b88b30 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jonas=20=C3=85dahl?= -Date: Thu, 18 Jun 2020 13:14:04 +0200 -Subject: [PATCH] vnc/pipewire-stream: Remove assert - -Handle lack of frames gracefully. ---- - src/grd-vnc-pipewire-stream.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/src/grd-vnc-pipewire-stream.c b/src/grd-vnc-pipewire-stream.c -index ee8ad5d..a3f5fb6 100644 ---- a/src/grd-vnc-pipewire-stream.c -+++ b/src/grd-vnc-pipewire-stream.c -@@ -463,7 +463,6 @@ on_stream_process (void *user_data) - - frame = process_buffer (stream, buffer->buffer); - -- g_assert (frame); - g_mutex_lock (&stream->frame_mutex); - if (stream->pending_frame) - { --- -2.26.2 - diff --git a/SOURCES/0002-vnc-pipewire-stream-Only-try-to-copy-frame-pixels-if.patch b/SOURCES/0002-vnc-pipewire-stream-Only-try-to-copy-frame-pixels-if.patch deleted file mode 100644 index ef46648..0000000 --- a/SOURCES/0002-vnc-pipewire-stream-Only-try-to-copy-frame-pixels-if.patch +++ /dev/null @@ -1,62 +0,0 @@ -From f3efe25a5cb173bc63b380619b8673cd5ba99f6f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jonas=20=C3=85dahl?= -Date: Thu, 18 Jun 2020 11:35:44 +0200 -Subject: [PATCH 2/2] vnc/pipewire-stream: Only try to copy frame pixels if - there are any - -The producer might send empty frames with only cursor metadata, and in -this case we shouldn't try to copy any pixels, as there are no. ---- - src/grd-vnc-pipewire-stream.c | 28 ++++++++++++++++------------ - 1 file changed, 16 insertions(+), 12 deletions(-) - -diff --git a/src/grd-vnc-pipewire-stream.c b/src/grd-vnc-pipewire-stream.c -index 91fb0a1..ee8ad5d 100644 ---- a/src/grd-vnc-pipewire-stream.c -+++ b/src/grd-vnc-pipewire-stream.c -@@ -312,9 +312,6 @@ process_buffer (GrdVncPipeWireStream *stream, - size_t size; - uint8_t *map; - void *src_data; -- int src_stride; -- int dst_stride; -- int height; - int y; - struct spa_meta_cursor *spa_meta_cursor; - g_autofree GrdVncFrame *frame = NULL; -@@ -365,16 +362,23 @@ process_buffer (GrdVncPipeWireStream *stream, - return NULL; - } - -- src_stride = buffer->datas[0].chunk->stride; -- dst_stride = grd_session_vnc_get_framebuffer_stride (stream->session); -- height = stream->spa_format.size.height; -- -- frame->data = g_malloc (height * dst_stride); -- for (y = 0; y < height; y++) -+ if (src_data) - { -- memcpy (((uint8_t *) frame->data) + y * dst_stride, -- ((uint8_t *) src_data) + y * src_stride, -- dst_stride); -+ int src_stride; -+ int dst_stride; -+ int height; -+ -+ src_stride = buffer->datas[0].chunk->stride; -+ dst_stride = grd_session_vnc_get_framebuffer_stride (stream->session); -+ height = stream->spa_format.size.height; -+ -+ frame->data = g_malloc (height * dst_stride); -+ for (y = 0; y < height; y++) -+ { -+ memcpy (((uint8_t *) frame->data) + y * dst_stride, -+ ((uint8_t *) src_data) + y * src_stride, -+ dst_stride); -+ } - } - - if (map) --- -2.26.2 - diff --git a/SOURCES/cursor-only-frame-fixes.patch b/SOURCES/cursor-only-frame-fixes.patch deleted file mode 100644 index 228ff15..0000000 --- a/SOURCES/cursor-only-frame-fixes.patch +++ /dev/null @@ -1,127 +0,0 @@ -From f97b689c5c67cee36025a7b0a9210deb8b373b03 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jonas=20=C3=85dahl?= -Date: Fri, 3 Jul 2020 17:03:52 +0200 -Subject: [PATCH 1/3] session-vnc: Add API to flush - -When no damage is to be reported, but e.g. cursor moved, we need to -flush, so add API to make this possible. - -(cherry picked from commit 25e61a7ed3631687aed4310824e7810088e63b37) ---- - src/grd-session-vnc.c | 6 ++++++ - src/grd-session-vnc.h | 2 ++ - 2 files changed, 8 insertions(+) - -diff --git a/src/grd-session-vnc.c b/src/grd-session-vnc.c -index 9fcbb69..7950d1e 100644 ---- a/src/grd-session-vnc.c -+++ b/src/grd-session-vnc.c -@@ -179,6 +179,12 @@ grd_session_vnc_take_buffer (GrdSessionVnc *session_vnc, - rfbProcessEvents (session_vnc->rfb_screen, 0); - } - -+void -+grd_session_vnc_flush (GrdSessionVnc *session_vnc) -+{ -+ rfbProcessEvents (session_vnc->rfb_screen, 0); -+} -+ - void - grd_session_vnc_set_cursor (GrdSessionVnc *session_vnc, - rfbCursorPtr rfb_cursor) -diff --git a/src/grd-session-vnc.h b/src/grd-session-vnc.h -index 294860e..a065857 100644 ---- a/src/grd-session-vnc.h -+++ b/src/grd-session-vnc.h -@@ -49,6 +49,8 @@ void grd_session_vnc_queue_resize_framebuffer (GrdSessionVnc *session_vnc, - void grd_session_vnc_take_buffer (GrdSessionVnc *session_vnc, - void *data); - -+void grd_session_vnc_flush (GrdSessionVnc *session_vnc); -+ - void grd_session_vnc_set_cursor (GrdSessionVnc *session_vnc, - rfbCursorPtr rfb_cursor); - --- -2.26.2 - - -From 8a050b66be76d73725ac7665295160ab6c40b0f5 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jonas=20=C3=85dahl?= -Date: Fri, 3 Jul 2020 17:12:58 +0200 -Subject: [PATCH 2/3] vnc-pipewire-stream: Properly process cursor-change-only - frames - -Such frames will have the buffer data size set to 0, as it is empty, but -may contain metadata carrying the cursor update. - -(cherry picked from commit c04762a450ea9a21730db26c296c1283e121dc08) ---- - src/grd-vnc-pipewire-stream.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/src/grd-vnc-pipewire-stream.c b/src/grd-vnc-pipewire-stream.c -index a3f5fb6..7519377 100644 ---- a/src/grd-vnc-pipewire-stream.c -+++ b/src/grd-vnc-pipewire-stream.c -@@ -312,7 +312,6 @@ process_buffer (GrdVncPipeWireStream *stream, - size_t size; - uint8_t *map; - void *src_data; -- int y; - struct spa_meta_cursor *spa_meta_cursor; - g_autofree GrdVncFrame *frame = NULL; - -@@ -320,8 +319,8 @@ process_buffer (GrdVncPipeWireStream *stream, - - if (buffer->datas[0].chunk->size == 0) - { -- g_warning ("Received empty buffer"); -- return NULL; -+ map = NULL; -+ src_data = NULL; - } - else if (buffer->datas[0].type == SPA_DATA_MemFd) - { -@@ -367,6 +366,7 @@ process_buffer (GrdVncPipeWireStream *stream, - int src_stride; - int dst_stride; - int height; -+ int y; - - src_stride = buffer->datas[0].chunk->stride; - dst_stride = grd_session_vnc_get_framebuffer_stride (stream->session); --- -2.26.2 - - -From eac6368d8411c586007df8b1a2d85df3da1b55c5 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jonas=20=C3=85dahl?= -Date: Fri, 3 Jul 2020 17:13:58 +0200 -Subject: [PATCH 3/3] vnc-pipewire-stream: Flush connection if no new pixel - buffer - -Otherwise we'll wait on input until we flush out our new cursor move -only output. - -(cherry picked from commit 3394e34c3c502d63636bb852c062855c46736a6f) ---- - src/grd-vnc-pipewire-stream.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/src/grd-vnc-pipewire-stream.c b/src/grd-vnc-pipewire-stream.c -index 7519377..791b71d 100644 ---- a/src/grd-vnc-pipewire-stream.c -+++ b/src/grd-vnc-pipewire-stream.c -@@ -299,6 +299,8 @@ do_render (struct spa_loop *loop, - - if (frame->data) - grd_session_vnc_take_buffer (stream->session, frame->data); -+ else -+ grd_session_vnc_flush (stream->session); - - g_free (frame); - --- -2.26.2 - diff --git a/SPECS/gnome-remote-desktop.spec b/SPECS/gnome-remote-desktop.spec deleted file mode 100644 index f858cab..0000000 --- a/SPECS/gnome-remote-desktop.spec +++ /dev/null @@ -1,148 +0,0 @@ -%global systemd_unit gnome-remote-desktop.service - -Name: gnome-remote-desktop -Version: 0.1.8 -Release: 4%{?dist} -Summary: GNOME Remote Desktop screen share service - -License: GPLv2+ -URL: https://gitlab.gnome.org/jadahl/gnome-remote-desktop -Source0: https://gitlab.gnome.org/jadahl/gnome-remote-desktop/uploads/20e4965351cdbd8dc32ff9801e884b91/gnome-remote-desktop-0.1.8.tar.xz - -# Fix black screen on Wayland -Patch1: 0001-vnc-pipewire-stream-Handle-stride-mismatch.patch - -# Anon TLS encryption support -Patch2: anon-tls-support.patch - -# Don't crash on metadata only buffers (#1847062) -Patch3: 0001-stream-log-a-warning-on-error.patch -Patch4: 0002-vnc-pipewire-stream-Only-try-to-copy-frame-pixels-if.patch -Patch5: 0001-vnc-pipewire-stream-Remove-assert.patch - -# Cursor only frame fixes (#1837406) -Patch6: cursor-only-frame-fixes.patch - -# Connection throttling (RHEL-92791) -Patch7: connection-throttling.patch - -BuildRequires: git -BuildRequires: gcc -BuildRequires: meson >= 0.36.0 -BuildRequires: pkgconfig -BuildRequires: pkgconfig(glib-2.0) >= 2.32 -BuildRequires: pkgconfig(gio-unix-2.0) >= 2.32 -BuildRequires: pkgconfig(libpipewire-0.3) >= 0.3.4 -BuildRequires: pkgconfig(libvncserver) >= 0.9.11-7 -BuildRequires: pkgconfig(libsecret-1) -BuildRequires: pkgconfig(libnotify) -BuildRequires: pkgconfig(gnutls) -BuildRequires: python3-devel - -%{?systemd_requires} -BuildRequires: systemd - -Requires: pipewire >= 0.3.4 - -%description -GNOME Remote Desktop is a remote desktop and screen sharing service for the -GNOME desktop environment. - - -%prep -%autosetup -S git - - -%build -%meson -%meson_build - - -%install -%meson_install - - -%post -%systemd_user_post %{systemd_unit} - - -%preun -%systemd_user_preun %{systemd_unit} - - -%postun -%systemd_user_postun_with_restart %{systemd_unit} - - -%files -%license COPYING -%doc README -%{_libexecdir}/gnome-remote-desktop-daemon -%{_userunitdir}/gnome-remote-desktop.service -%{_datadir}/glib-2.0/schemas/org.gnome.desktop.remote-desktop.gschema.xml -%{_datadir}/glib-2.0/schemas/org.gnome.desktop.remote-desktop.enums.xml - - -%changelog -* Thu Jul 03 2025 Jonas Ådahl - 0.1.8-4 -- Backport connection throttling - Resolves: RHEL-92791 - -* Wed Jul 15 2020 Jonas Ådahl - 0.1.8-3 -- Backport cursor only frame fixes - Related: #1837406 - -* Thu Jun 18 2020 Jonas Ådahl - 0.1.8-2 -- Don't crash on metadata only buffers - Resolves: #1847062 - -* Wed May 20 2020 Jonas Ådahl - 0.1.8-1 -- Rebase to 0.1.8 - Resolves: #1837406 - -* Wed Nov 27 2019 Jonas Ådahl - 0.1.6-8 -- Update patch to handle older libvncserver at build time - Resolves: #1684729 - -* Wed Nov 27 2019 Jonas Ådahl - 0.1.6-7 -- Handle auth settings changes - Resolves: #1684729 - -* Wed Nov 27 2019 Jonas Ådahl - 0.1.6-6 -- Fix initial black content issue - Resolves: #1765448 - -* Thu May 30 2019 Tomáš Popela - 0.1.6-5 -- Bump the version to make gating happy - that's bug 1681618 -- Resolves: rhbz#1713330 - -* Fri May 24 2019 Jonas Ådahl - 0.1.6-4 -- Backport password override test helper (rhbz#1713330) - -* Thu Jan 3 2019 Jonas Ådahl - 0.1.6-3 -- Backport various fixes (rhbz#1659118) - -* Mon Oct 1 2018 Jonas Ådahl - 0.1.6-2 -- Don't crash when PipeWire disconnects (rhbz#1627469) - -* Tue Aug 7 2018 Jonas Ådahl - 0.1.6 -- Update to 0.1.6 -- Apply ANON-TLS patch -- Depend on pipewire 0.2.2 - -* Tue Aug 29 2017 Jonas Ådahl - 0.1.2-3 -- Use %%autosetup -- Install licence file - -* Tue Aug 22 2017 Jonas Ådahl - 0.1.2-2 -- Remove gschema compilation step as that had been deprecated - -* Mon Aug 21 2017 Jonas Ådahl - 0.1.2-1 -- Update to 0.1.2 -- Changed tabs to spaces -- Added systemd user macros -- Install to correct systemd user unit directory -- Compile gsettings schemas after install and uninstall - -* Mon Aug 21 2017 Jonas Ådahl - 0.1.1-1 -- First packaged version diff --git a/SOURCES/connection-throttling.patch b/connection-throttling.patch similarity index 62% rename from SOURCES/connection-throttling.patch rename to connection-throttling.patch index 50aa191..a3f7c63 100644 --- a/SOURCES/connection-throttling.patch +++ b/connection-throttling.patch @@ -1,80 +1,263 @@ -From 1ee5b053496fcd9de7990d05e8180d548e8ce0da Mon Sep 17 00:00:00 2001 +From 7a7a6d0757829f2efb2fc416b1ba55aa52216c4b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Mon, 26 May 2025 16:08:54 +0200 +Subject: [PATCH 01/13] control: Allow controlling all daemon types + +Useful for gracefully terminating daemon without sending signals. +--- + src/grd-control.c | 23 ++++++++++++++++++++++- + 1 file changed, 22 insertions(+), 1 deletion(-) + +diff --git a/src/grd-control.c b/src/grd-control.c +index 858ab10a..284cb113 100644 +--- a/src/grd-control.c ++++ b/src/grd-control.c +@@ -33,13 +33,25 @@ main (int argc, char **argv) + { + g_autoptr(GApplication) app = NULL; + gboolean terminate = FALSE; ++ gboolean headless = FALSE; ++ gboolean system = FALSE; ++ gboolean handover = FALSE; + GOptionEntry entries[] = { + { "terminate", 0, 0, G_OPTION_ARG_NONE, &terminate, + "Terminate the daemon", NULL }, ++ { "headless", 0, 0, G_OPTION_ARG_NONE, &headless, ++ "Control headless daemon", NULL }, ++#if defined(HAVE_RDP) && defined(HAVE_LIBSYSTEMD) ++ { "system", 0, 0, G_OPTION_ARG_NONE, &system, ++ "Control system daemon", NULL }, ++ { "handover", 0, 0, G_OPTION_ARG_NONE, &handover, ++ "Control handover daemon", NULL }, ++#endif /* HAVE_RDP && HAVE_LIBSYSTEMD */ + { NULL } + }; + GError *error = NULL; + GOptionContext *context; ++ const char *app_id; + + context = g_option_context_new ("- control gnome-remote-desktop"); + g_option_context_add_main_entries (context, entries, NULL); +@@ -56,7 +68,16 @@ main (int argc, char **argv) + return 1; + } + +- app = g_application_new (GRD_DAEMON_USER_APPLICATION_ID, 0); ++ if (headless) ++ app_id = GRD_DAEMON_HEADLESS_APPLICATION_ID; ++ else if (system) ++ app_id = GRD_DAEMON_SYSTEM_APPLICATION_ID; ++ else if (handover) ++ app_id = GRD_DAEMON_HANDOVER_APPLICATION_ID; ++ else ++ app_id = GRD_DAEMON_USER_APPLICATION_ID; ++ ++ app = g_application_new (app_id, G_APPLICATION_DEFAULT_FLAGS); + if (!g_application_register (app, NULL, NULL)) + { + g_warning ("Failed to register with application\n"); +-- +2.49.0 + + +From 8dcf988fb40ca328d685d3ca3cf2e7f5e2e19467 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Mon, 26 May 2025 16:09:45 +0200 -Subject: [PATCH 1/7] daemon: Use GError auto pointer +Subject: [PATCH 02/13] daemon: Use GError auto pointer --- - src/grd-daemon.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) + src/grd-daemon.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/grd-daemon.c b/src/grd-daemon.c -index 6f7bb460..f5595005 100644 +index b99f6181..2f6ed024 100644 --- a/src/grd-daemon.c +++ b/src/grd-daemon.c -@@ -292,7 +292,7 @@ main (int argc, char **argv) +@@ -986,7 +986,7 @@ main (int argc, char **argv) }; - g_autoptr(GOptionContext) context = NULL; - g_autoptr(GApplication) app = NULL; + g_autoptr (GOptionContext) option_context = NULL; + g_autoptr (GrdDaemon) daemon = NULL; - GError *error = NULL; + g_autoptr (GError) error = NULL; + GrdRuntimeMode runtime_mode; g_set_application_name (_("GNOME Remote Desktop")); - -@@ -301,7 +301,6 @@ main (int argc, char **argv) - if (!g_option_context_parse (context, &argc, &argv, &error)) +@@ -996,7 +996,6 @@ main (int argc, char **argv) + if (!g_option_context_parse (option_context, &argc, &argv, &error)) { g_printerr ("Invalid option: %s\n", error->message); - g_error_free (error); return EXIT_FAILURE; } +@@ -1045,7 +1044,6 @@ main (int argc, char **argv) + if (!daemon) + { + g_printerr ("Failed to initialize: %s\n", error->message); +- g_error_free (error); + return EXIT_FAILURE; + } + -- 2.49.0 -From 29e0f5834079069fd445e4a0b643c671eb404dc2 Mon Sep 17 00:00:00 2001 +From dfa19a9498f7245ac0ce3efd290dde1bdd8b865f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Mon, 26 May 2025 17:04:45 +0200 +Subject: [PATCH 03/13] rdp-server: Remove empty constructor vfunc + +No need to implement it if it doesn't do anything. +--- + src/grd-rdp-server.c | 7 ------- + 1 file changed, 7 deletions(-) + +diff --git a/src/grd-rdp-server.c b/src/grd-rdp-server.c +index 4fddfaa2..6ee93c5c 100644 +--- a/src/grd-rdp-server.c ++++ b/src/grd-rdp-server.c +@@ -470,12 +470,6 @@ grd_rdp_server_dispose (GObject *object) + G_OBJECT_CLASS (grd_rdp_server_parent_class)->dispose (object); + } + +-static void +-grd_rdp_server_constructed (GObject *object) +-{ +- G_OBJECT_CLASS (grd_rdp_server_parent_class)->constructed (object); +-} +- + static void + grd_rdp_server_init (GrdRdpServer *rdp_server) + { +@@ -498,7 +492,6 @@ grd_rdp_server_class_init (GrdRdpServerClass *klass) + object_class->set_property = grd_rdp_server_set_property; + object_class->get_property = grd_rdp_server_get_property; + object_class->dispose = grd_rdp_server_dispose; +- object_class->constructed = grd_rdp_server_constructed; + + g_object_class_install_property (object_class, + PROP_CONTEXT, +-- +2.49.0 + + +From 0a5400d11a032ae0e1b9e75bc72915b892713a77 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Wed, 28 May 2025 14:08:12 +0200 +Subject: [PATCH 04/13] rdp-sam: Dup fd kept in struct + +The SAM file instance intends to keeps the file descriptor alive so that +it doesn't go away; however it failed to do this due to fdopen() taking +ownership of it, thus closing it during fclose(). This meant we'd close +an arbitrary potentially reused file descriptor when the SAM file +instance eventually got cleaned up. Address this by reordering things a +bit, while putting a duplicated file descriptor in the SAM file instance +struct. +--- + src/grd-rdp-sam.c | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +diff --git a/src/grd-rdp-sam.c b/src/grd-rdp-sam.c +index 5898825a..bcadcb59 100644 +--- a/src/grd-rdp-sam.c ++++ b/src/grd-rdp-sam.c +@@ -76,7 +76,7 @@ grd_rdp_sam_create_sam_file (const char *username, + g_autofree char *file_dir = NULL; + g_autofree char *filename = NULL; + g_autofree char *sam_string = NULL; +- int fd; ++ g_autofd int fd = -1; + FILE *sam_file; + + file_dir = g_strdup_printf ("%s%s", g_get_user_runtime_dir (), grd_path); +@@ -98,20 +98,21 @@ grd_rdp_sam_create_sam_file (const char *username, + return NULL; + } + +- rdp_sam_file = g_new0 (GrdRdpSAMFile, 1); +- rdp_sam_file->fd = fd; +- rdp_sam_file->filename = g_steal_pointer (&filename); +- +- sam_string = create_sam_string (username, password); +- +- sam_file = fdopen (rdp_sam_file->fd, "w+"); ++ sam_file = fdopen (fd, "w+"); + if (!sam_file) + { + g_warning ("[RDP] Failed to open SAM database: %s", g_strerror (errno)); +- grd_rdp_sam_free_sam_file (rdp_sam_file); + return NULL; + } + ++ rdp_sam_file = g_new0 (GrdRdpSAMFile, 1); ++ rdp_sam_file->fd = dup (fd); ++ rdp_sam_file->filename = g_steal_pointer (&filename); ++ ++ g_steal_fd (&fd); ++ ++ sam_string = create_sam_string (username, password); ++ + fputs (sam_string, sam_file); + fclose (sam_file); + +-- +2.49.0 + + +From 6a965f7c383a62e06a1dfb5033e7820ddff5c242 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Wed, 28 May 2025 22:33:54 +0200 +Subject: [PATCH 05/13] rdp-server: Set socket backlog count to 5 + +This limits the number of pending connections. +--- + src/grd-rdp-server.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/grd-rdp-server.c b/src/grd-rdp-server.c +index 6ee93c5c..537d4e30 100644 +--- a/src/grd-rdp-server.c ++++ b/src/grd-rdp-server.c +@@ -35,6 +35,7 @@ + + #define RDP_SERVER_N_BINDING_ATTEMPTS 10 + #define RDP_SERVER_BINDING_ATTEMPT_INTERVAL_MS 500 ++#define RDP_SERVER_SOCKET_BACKLOG_COUNT 5 + + enum + { +@@ -302,6 +303,9 @@ bind_socket (GrdRdpServer *rdp_server, + uint16_t selected_rdp_port = 0; + gboolean negotiate_port; + ++ g_socket_listener_set_backlog (G_SOCKET_LISTENER (rdp_server), ++ RDP_SERVER_SOCKET_BACKLOG_COUNT); ++ + g_object_get (G_OBJECT (settings), + "rdp-port", &rdp_port, + "rdp-negotiate-port", &negotiate_port, +-- +2.49.0 + + +From bc1ab53a393b886d3e5fae5b33efb8f2d3205fbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 28 May 2025 22:55:20 +0200 -Subject: [PATCH 2/7] utils: Add some time conversion helpers +Subject: [PATCH 06/13] utils: Add some time conversion helpers Useful when converting between second, microseconds, etc. --- - src/grd-utils.h | 44 ++++++++++++++++++++++++++++++++++++++++++++ - src/meson.build | 1 + - 2 files changed, 45 insertions(+) - create mode 100644 src/grd-utils.h + src/grd-utils.h | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) diff --git a/src/grd-utils.h b/src/grd-utils.h -new file mode 100644 -index 00000000..9fdb020a ---- /dev/null +index 6e433246..d9ae0801 100644 +--- a/src/grd-utils.h +++ b/src/grd-utils.h -@@ -0,0 +1,44 @@ -+/* -+ * Copyright (C) 2022 Pascal Nowack -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -+ * 02111-1307, USA. -+ */ -+ -+#ifndef GRD_UTILS_H -+#define GRD_UTILS_H -+ -+#include -+#include -+ +@@ -98,4 +98,22 @@ gboolean grd_systemd_unit_get_active_state (GDBusProxy *unit_pro + GrdSystemdUnitActiveState *active_state, + GError **error); + +static inline int64_t +us (int64_t us) +{ @@ -93,69 +276,32 @@ index 00000000..9fdb020a + return ms2us (s * 1000); +} + -+#endif /* GRD_UTILS_H */ -diff --git a/src/meson.build b/src/meson.build -index 9d2f1cea..a2d738ac 100644 ---- a/src/meson.build -+++ b/src/meson.build -@@ -15,6 +15,7 @@ daemon_sources = files([ - 'grd-stream.c', - 'grd-stream.h', - 'grd-types.h', -+ 'grd-utils.h', - 'grd-vnc-cursor.c', - 'grd-vnc-cursor.h', - 'grd-vnc-pipewire-stream.c', + #endif /* GRD_UTILS_H */ -- 2.49.0 -From 72ea71aa2a4696ff51b22d86f11adc9f0dbff1d8 Mon Sep 17 00:00:00 2001 +From 0f90337b241b200fc33565d49b6344e43d93bd0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Mon, 30 Jun 2025 16:16:31 +0200 -Subject: [PATCH 3/7] utils: Add helper to close connection and notify +Subject: [PATCH 07/13] utils: Add helper to close connection and notify Closing doesn't notify that it was closed, so lets add a helper that does so, that we then can uses to rely on the closed property being up to date. --- - src/grd-utils.c | 32 ++++++++++++++++++++++++++++++++ - src/grd-utils.h | 2 ++ - src/meson.build | 1 + - 3 files changed, 35 insertions(+) - create mode 100644 src/grd-utils.c + src/grd-utils.c | 7 +++++++ + src/grd-utils.h | 2 ++ + 2 files changed, 9 insertions(+) diff --git a/src/grd-utils.c b/src/grd-utils.c -new file mode 100644 -index 00000000..772d6fc4 ---- /dev/null +index 9ded2092..20e6bffa 100644 +--- a/src/grd-utils.c +++ b/src/grd-utils.c -@@ -0,0 +1,32 @@ -+/* -+ * Copyright (C) 2010 Intel Corp. -+ * Copyright (C) 2014 Jonas Ådahl -+ * Copyright (C) 2016-2022 Red Hat Inc. -+ * Copyright (C) 2022 Pascal Nowack -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -+ * 02111-1307, USA. -+ */ -+ -+#include "config.h" -+ -+#include "grd-utils.h" +@@ -461,3 +461,10 @@ grd_systemd_unit_get_active_state (GDBusProxy *unit_proxy, + + return TRUE; + } + +void +grd_close_connection_and_notify (GSocketConnection *connection) @@ -164,38 +310,26 @@ index 00000000..772d6fc4 + g_object_notify (G_OBJECT (connection), "closed"); +} diff --git a/src/grd-utils.h b/src/grd-utils.h -index 9fdb020a..6fb81717 100644 +index d9ae0801..eeb0a01c 100644 --- a/src/grd-utils.h +++ b/src/grd-utils.h -@@ -23,6 +23,8 @@ - #include - #include +@@ -98,6 +98,8 @@ gboolean grd_systemd_unit_get_active_state (GDBusProxy *unit_pro + GrdSystemdUnitActiveState *active_state, + GError **error); +void grd_close_connection_and_notify (GSocketConnection *connection); + static inline int64_t us (int64_t us) { -diff --git a/src/meson.build b/src/meson.build -index a2d738ac..de6b8cff 100644 ---- a/src/meson.build -+++ b/src/meson.build -@@ -15,6 +15,7 @@ daemon_sources = files([ - 'grd-stream.c', - 'grd-stream.h', - 'grd-types.h', -+ 'grd-utils.c', - 'grd-utils.h', - 'grd-vnc-cursor.c', - 'grd-vnc-cursor.h', -- 2.49.0 -From 5104e01271fadbefcc277b46cf49c15f977727fa Mon Sep 17 00:00:00 2001 +From 4e09eee9a71e8da5bc1fb0fcaac999fc8efff953 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 28 May 2025 22:40:38 +0200 -Subject: [PATCH 4/7] Introduce throttler class +Subject: [PATCH 08/13] Introduce throttler class This handles the throttling of incoming connections, and is intended to act as a first line of defence against denial of service attacks. It @@ -744,11 +878,11 @@ index 00000000..d57d653a + +#endif /* GRD_THROTTLER_H */ diff --git a/src/meson.build b/src/meson.build -index de6b8cff..26a1039c 100644 +index f92f9f1e..1e2cc69c 100644 --- a/src/meson.build +++ b/src/meson.build -@@ -14,6 +14,8 @@ daemon_sources = files([ - 'grd-settings.h', +@@ -72,6 +72,8 @@ daemon_sources = files([ + 'grd-settings-user.h', 'grd-stream.c', 'grd-stream.h', + 'grd-throttler.c', @@ -760,19 +894,167 @@ index de6b8cff..26a1039c 100644 2.49.0 -From c1a2a397f80ea4df6f8d7e7bd116c90ff6f9bb70 Mon Sep 17 00:00:00 2001 +From 1dbffe778f0392a64c69152083290f125bfb450f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Wed, 28 May 2025 22:46:27 +0200 +Subject: [PATCH 09/13] rdp-server: Throttle connections using GrdThrottler + +This avoids system resource exhaustion by a single attacker. + +Related: CVE-2025-5024 +--- + src/grd-rdp-server.c | 27 +++++++++++++++++++++++---- + src/grd-session-rdp.c | 6 ++++++ + 2 files changed, 29 insertions(+), 4 deletions(-) + +diff --git a/src/grd-rdp-server.c b/src/grd-rdp-server.c +index 537d4e30..228939b5 100644 +--- a/src/grd-rdp-server.c ++++ b/src/grd-rdp-server.c +@@ -31,6 +31,7 @@ + #include "grd-context.h" + #include "grd-hwaccel-nvidia.h" + #include "grd-session-rdp.h" ++#include "grd-throttler.h" + #include "grd-utils.h" + + #define RDP_SERVER_N_BINDING_ATTEMPTS 10 +@@ -59,6 +60,8 @@ struct _GrdRdpServer + { + GSocketService parent; + ++ GrdThrottler *throttler; ++ + GList *sessions; + + GList *stopped_sessions; +@@ -216,13 +219,25 @@ on_incoming (GSocketService *service, + GSocketConnection *connection) + { + GrdRdpServer *rdp_server = GRD_RDP_SERVER (service); ++ ++ grd_throttler_handle_connection (rdp_server->throttler, ++ connection); ++ return TRUE; ++} ++ ++static void ++allow_connection_cb (GrdThrottler *throttler, ++ GSocketConnection *connection, ++ gpointer user_data) ++{ ++ GrdRdpServer *rdp_server = GRD_RDP_SERVER (user_data); + GrdSessionRdp *session_rdp; + +- g_debug ("New incoming RDP connection"); ++ g_debug ("Creating new RDP session"); + + if (!(session_rdp = grd_session_rdp_new (rdp_server, connection, + rdp_server->hwaccel_nvidia))) +- return TRUE; ++ return; + + rdp_server->sessions = g_list_append (rdp_server->sessions, session_rdp); + +@@ -233,8 +248,6 @@ on_incoming (GSocketService *service, + g_signal_connect (session_rdp, "post-connected", + G_CALLBACK (on_session_post_connect), + rdp_server); +- +- return TRUE; + } + + void +@@ -410,6 +423,8 @@ grd_rdp_server_stop (GrdRdpServer *rdp_server) + g_clear_handle_id (&rdp_server->cleanup_sessions_idle_id, g_source_remove); + grd_rdp_server_cleanup_stopped_sessions (rdp_server); + ++ g_clear_object (&rdp_server->throttler); ++ + if (rdp_server->cancellable) + { + g_cancellable_cancel (rdp_server->cancellable); +@@ -468,6 +483,7 @@ grd_rdp_server_dispose (GObject *object) + g_assert (!rdp_server->binding_timeout_source_id); + g_assert (!rdp_server->cleanup_sessions_idle_id); + g_assert (!rdp_server->stopped_sessions); ++ g_assert (!rdp_server->throttler); + + g_assert (!rdp_server->hwaccel_nvidia); + +@@ -477,6 +493,9 @@ grd_rdp_server_dispose (GObject *object) + static void + grd_rdp_server_init (GrdRdpServer *rdp_server) + { ++ rdp_server->throttler = grd_throttler_new (allow_connection_cb, ++ rdp_server); ++ + rdp_server->pending_binding_attempts = RDP_SERVER_N_BINDING_ATTEMPTS; + + winpr_InitializeSSL (WINPR_SSL_INIT_DEFAULT); +diff --git a/src/grd-session-rdp.c b/src/grd-session-rdp.c +index 3bf1fb7a..bdccc981 100644 +--- a/src/grd-session-rdp.c ++++ b/src/grd-session-rdp.c +@@ -47,6 +47,7 @@ + #include "grd-rdp-session-metrics.h" + #include "grd-rdp-telemetry.h" + #include "grd-settings.h" ++#include "grd-utils.h" + + #define MAX_MONITOR_COUNT_HEADLESS 16 + #define MAX_MONITOR_COUNT_SCREEN_SHARE 1 +@@ -1577,6 +1578,7 @@ grd_session_rdp_stop (GrdSession *session) + g_clear_object (&session_rdp->renderer); + + peer->Close (peer); ++ grd_close_connection_and_notify (session_rdp->connection); + g_clear_object (&session_rdp->connection); + + g_clear_object (&rdp_peer_context->network_autodetection); +@@ -1761,6 +1763,10 @@ grd_session_rdp_dispose (GObject *object) + g_clear_object (&session_rdp->layout_manager); + clear_rdp_peer (session_rdp); + ++ if (session_rdp->connection) ++ grd_close_connection_and_notify (session_rdp->connection); ++ g_clear_object (&session_rdp->connection); ++ + g_clear_object (&session_rdp->renderer); + + g_clear_object (&session_rdp->rdp_event_queue); +-- +2.49.0 + + +From 61aa2a856d920ecc64abf38dfb1ca089f2626192 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Fri, 30 May 2025 16:54:00 +0200 -Subject: [PATCH 5/7] throttler: Introduce limits struct +Subject: [PATCH 10/13] throttler: Introduce limits struct This will be used by the server implementation to customize throttling limits. This will be used by the VNC server to limit to one global session at a time, replacing it's own existing condition. --- - src/grd-throttler.c | 64 +++++++++++++++++++++++++++++++++++++-------- - src/grd-throttler.h | 14 ++++++++-- - 2 files changed, 65 insertions(+), 13 deletions(-) + src/grd-rdp-server.c | 3 ++- + src/grd-throttler.c | 64 ++++++++++++++++++++++++++++++++++++-------- + src/grd-throttler.h | 14 ++++++++-- + 3 files changed, 67 insertions(+), 14 deletions(-) +diff --git a/src/grd-rdp-server.c b/src/grd-rdp-server.c +index 228939b5..207d9e2d 100644 +--- a/src/grd-rdp-server.c ++++ b/src/grd-rdp-server.c +@@ -493,7 +493,8 @@ grd_rdp_server_dispose (GObject *object) + static void + grd_rdp_server_init (GrdRdpServer *rdp_server) + { +- rdp_server->throttler = grd_throttler_new (allow_connection_cb, ++ rdp_server->throttler = grd_throttler_new (grd_throttler_limits_new (), ++ allow_connection_cb, + rdp_server); + + rdp_server->pending_binding_attempts = RDP_SERVER_N_BINDING_ATTEMPTS; diff --git a/src/grd-throttler.c b/src/grd-throttler.c index e584433a..0429a089 100644 --- a/src/grd-throttler.c @@ -960,23 +1242,23 @@ index d57d653a..9e72b8f1 100644 2.49.0 -From 70a97969a131bd64f0e7e529c592fa6a7ecbb6b6 Mon Sep 17 00:00:00 2001 +From a0fa2c8afb072d2aa0886012925eccc36c2cdfb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Fri, 30 May 2025 16:55:46 +0200 -Subject: [PATCH 6/7] vnc-server: Hook up VNC server to the throttler +Subject: [PATCH 11/13] vnc-server: Hook up VNC server to the throttler This allows us to replace existing single session limitation with limiting the throttler to one accepted connection at any given time. --- src/grd-session-vnc.c | 2 ++ - src/grd-vnc-server.c | 45 +++++++++++++++++++++++++++++++++++-------- - 2 files changed, 39 insertions(+), 8 deletions(-) + src/grd-vnc-server.c | 48 +++++++++++++++++++++++++++++++------------ + 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/grd-session-vnc.c b/src/grd-session-vnc.c -index 7950d1e0..fccbf741 100644 +index 6e118d88..8f4caec0 100644 --- a/src/grd-session-vnc.c +++ b/src/grd-session-vnc.c -@@ -32,6 +32,7 @@ +@@ -34,6 +34,7 @@ #include "grd-prompt.h" #include "grd-settings.h" #include "grd-stream.h" @@ -984,31 +1266,27 @@ index 7950d1e0..fccbf741 100644 #include "grd-vnc-server.h" #include "grd-vnc-pipewire-stream.h" -@@ -775,6 +776,7 @@ grd_session_vnc_stop (GrdSession *session) +@@ -942,6 +943,7 @@ grd_session_vnc_stop (GrdSession *session) grd_session_vnc_pause (session_vnc); + grd_close_connection_and_notify (session_vnc->connection); g_clear_object (&session_vnc->connection); + g_clear_object (&session_vnc->clipboard_vnc); g_clear_pointer (&session_vnc->rfb_screen->frameBuffer, g_free); - g_clear_pointer (&session_vnc->rfb_screen, rfbScreenCleanup); diff --git a/src/grd-vnc-server.c b/src/grd-vnc-server.c -index f9c68dba..f7240d37 100644 +index 2f8229b2..fc5020f0 100644 --- a/src/grd-vnc-server.c +++ b/src/grd-vnc-server.c -@@ -30,9 +30,10 @@ - +@@ -31,6 +31,7 @@ #include "grd-context.h" + #include "grd-debug.h" #include "grd-session-vnc.h" +#include "grd-throttler.h" -+#include "grd-utils.h" + #include "grd-utils.h" #include "grd-vnc-tls.h" -- - enum - { - PROP_0, -@@ -44,6 +45,8 @@ struct _GrdVncServer +@@ -45,6 +46,8 @@ struct _GrdVncServer { GSocketService parent; @@ -1017,9 +1295,9 @@ index f9c68dba..f7240d37 100644 GList *sessions; GList *stopped_sessions; -@@ -54,6 +57,11 @@ struct _GrdVncServer +@@ -55,6 +58,11 @@ struct _GrdVncServer - G_DEFINE_TYPE (GrdVncServer, grd_vnc_server, G_TYPE_SOCKET_SERVICE); + G_DEFINE_TYPE (GrdVncServer, grd_vnc_server, G_TYPE_SOCKET_SERVICE) +static void +allow_connection_cb (GrdThrottler *throttler, @@ -1029,7 +1307,7 @@ index f9c68dba..f7240d37 100644 GrdContext * grd_vnc_server_get_context (GrdVncServer *vnc_server) { -@@ -104,23 +112,24 @@ on_session_stopped (GrdSession *session, GrdVncServer *vnc_server) +@@ -105,22 +113,15 @@ on_session_stopped (GrdSession *session, GrdVncServer *vnc_server) } } @@ -1047,21 +1325,18 @@ index f9c68dba..f7240d37 100644 - g_debug ("New incoming VNC connection"); - - if (vnc_server->sessions) - { - /* TODO: Add the rfbScreen instance to GrdVncServer to support multiple - * sessions. */ - g_debug ("Refusing new VNC connection: already an active session"); +- if (vnc_server->sessions) +- { +- /* TODO: Add the rfbScreen instance to GrdVncServer to support multiple +- * sessions. */ +- g_message ("Refusing new VNC connection: already an active session"); - return TRUE; -+ return; - } - +- } + g_debug ("Creating new VNC session"); -+ + session_vnc = grd_session_vnc_new (vnc_server, connection); vnc_server->sessions = g_list_append (vnc_server->sessions, session_vnc); - grd_context_add_session (vnc_server->context, GRD_SESSION (session_vnc)); -@@ -128,7 +137,16 @@ on_incoming (GSocketService *service, +@@ -128,7 +129,16 @@ on_incoming (GSocketService *service, g_signal_connect (session_vnc, "stopped", G_CALLBACK (on_session_stopped), vnc_server); @@ -1078,16 +1353,24 @@ index f9c68dba..f7240d37 100644 return TRUE; } -@@ -252,6 +270,8 @@ grd_vnc_server_dispose (GObject *object) - vnc_server->sessions = NULL; - } - -+ g_clear_object (&vnc_server->throttler); +@@ -228,6 +238,8 @@ grd_vnc_server_stop (GrdVncServer *vnc_server) + grd_vnc_server_cleanup_stopped_sessions (vnc_server); + g_clear_handle_id (&vnc_server->cleanup_sessions_idle_id, + g_source_remove); + - G_OBJECT_CLASS (grd_vnc_server_parent_class)->dispose (object); ++ g_clear_object (&vnc_server->throttler); } -@@ -277,6 +297,15 @@ grd_vnc_server_constructed (GObject *object) + static void +@@ -276,6 +288,7 @@ grd_vnc_server_dispose (GObject *object) + g_assert (!vnc_server->sessions); + g_assert (!vnc_server->stopped_sessions); + g_assert (!vnc_server->cleanup_sessions_idle_id); ++ g_assert (!vnc_server->throttler); + + G_OBJECT_CLASS (grd_vnc_server_parent_class)->dispose (object); + } +@@ -302,6 +315,15 @@ grd_vnc_server_constructed (GObject *object) static void grd_vnc_server_init (GrdVncServer *vnc_server) { @@ -1107,10 +1390,36 @@ index f9c68dba..f7240d37 100644 2.49.0 -From 0f23aed843dacb1dceeb88cbeb9f545117d1c42d Mon Sep 17 00:00:00 2001 +From 5ba32deb4fca13b0a56d724f1bf79c5c76c39154 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Mon, 30 Jun 2025 16:01:12 +0200 +Subject: [PATCH 12/13] daemon: Add missing newline to error message + +--- + src/grd-daemon.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/grd-daemon.c b/src/grd-daemon.c +index 2f6ed024..2802bb1e 100644 +--- a/src/grd-daemon.c ++++ b/src/grd-daemon.c +@@ -1007,7 +1007,7 @@ main (int argc, char **argv) + + if (count_trues (3, headless, system, handover) > 1) + { +- g_printerr ("Invalid option: More than one runtime mode specified"); ++ g_printerr ("Invalid option: More than one runtime mode specified\n"); + return EXIT_FAILURE; + } + +-- +2.49.0 + + +From e94d1dd3015df17e88a7ee78f45d79aadfd45be6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Mon, 30 Jun 2025 16:01:37 +0200 -Subject: [PATCH 7/7] throttler: Allow overriding hard coded parallel +Subject: [PATCH 13/13] throttler: Allow overriding hard coded parallel connections limit Overriding is done via an argument passed to the daemon. This allows @@ -1119,46 +1428,48 @@ achieve by overriding the relevant systemd service file by both adding the --max-parallel-connections argument, as well as bumping the limit of number of open file descriptors to something adequate. --- - src/grd-daemon.c | 32 +++++++++++++++++++++++++++----- - src/grd-settings.c | 15 +++++++++++++++ + src/grd-daemon.c | 24 ++++++++++++++++++++++++ + src/grd-rdp-server.c | 19 +++++++++++++++---- + src/grd-settings.c | 19 +++++++++++++++++++ src/grd-settings.h | 5 +++++ src/grd-throttler.c | 9 ++++++--- src/grd-throttler.h | 4 +++- - src/grd-vnc-server.c | 17 +++++++++-------- - 6 files changed, 65 insertions(+), 17 deletions(-) + src/grd-vnc-server.c | 18 +++++++++--------- + 7 files changed, 81 insertions(+), 17 deletions(-) diff --git a/src/grd-daemon.c b/src/grd-daemon.c -index f5595005..e00304d8 100644 +index 2802bb1e..c04475a7 100644 --- a/src/grd-daemon.c +++ b/src/grd-daemon.c -@@ -35,6 +35,8 @@ - #include "grd-session.h" - #include "grd-vnc-server.h" +@@ -48,6 +48,8 @@ + + #define RDP_SERVER_RESTART_DELAY_MS 3000 +#define DEFAULT_MAX_PARALLEL_CONNECTIONS 10 + - struct _GrdDaemon + enum { - GApplication parent; -@@ -50,6 +52,9 @@ struct _GrdDaemon + PROP_0, +@@ -91,6 +93,9 @@ typedef struct _GrdDaemonPrivate - G_DEFINE_TYPE (GrdDaemon, grd_daemon, G_TYPE_APPLICATION) + G_DEFINE_TYPE_WITH_PRIVATE (GrdDaemon, grd_daemon, G_TYPE_APPLICATION) +#define QUOTE1(a) #a +#define QUOTE(a) QUOTE1(a) + - static gboolean - is_daemon_ready (GrdDaemon *daemon) - { -@@ -282,17 +287,23 @@ main (int argc, char **argv) - { - gboolean print_version = FALSE; + #ifdef HAVE_RDP + static void maybe_start_rdp_server (GrdDaemon *daemon); + #endif +@@ -966,6 +971,7 @@ main (int argc, char **argv) + gboolean handover = FALSE; + int rdp_port = -1; int vnc_port = -1; + int max_parallel_connections = DEFAULT_MAX_PARALLEL_CONNECTIONS; GOptionEntry entries[] = { { "version", 0, 0, G_OPTION_ARG_NONE, &print_version, - "Print version", NULL }, +@@ -982,6 +988,10 @@ main (int argc, char **argv) + "RDP port", NULL }, { "vnc-port", 0, 0, G_OPTION_ARG_INT, &vnc_port, "VNC port", NULL }, + { "max-parallel-connections", 0, 0, @@ -1167,90 +1478,130 @@ index f5595005..e00304d8 100644 + "default: " QUOTE(DEFAULT_MAX_PARALLEL_CONNECTIONS) ")", NULL }, { NULL } }; - g_autoptr(GOptionContext) context = NULL; - g_autoptr(GApplication) app = NULL; - g_autoptr (GError) error = NULL; -+ GrdSettings *settings; - - g_set_application_name (_("GNOME Remote Desktop")); - -@@ -317,13 +328,24 @@ main (int argc, char **argv) - - add_actions (app); - -- if (vnc_port != -1) -+ if (max_parallel_connections == 0) - { -- GrdSettings *settings; -- -- settings = grd_context_get_settings (GRD_DAEMON (app)->context); -- grd_settings_override_vnc_port (settings, vnc_port); -+ max_parallel_connections = INT_MAX; + g_autoptr (GOptionContext) option_context = NULL; +@@ -1011,6 +1021,17 @@ main (int argc, char **argv) + return EXIT_FAILURE; } + ++ if (max_parallel_connections == 0) ++ { ++ max_parallel_connections = INT_MAX; ++ } + else if (max_parallel_connections < 0) + { + g_printerr ("Invalid number of max parallel connections: %d\n", + max_parallel_connections); -+ return EXIT_SUCCESS; ++ return EXIT_FAILURE; + } + -+ settings = grd_context_get_settings (GRD_DAEMON (app)->context); -+ -+ if (vnc_port != -1) -+ grd_settings_override_vnc_port (settings, vnc_port); -+ + if (headless) + runtime_mode = GRD_RUNTIME_MODE_HEADLESS; + else if (system) +@@ -1057,5 +1078,8 @@ main (int argc, char **argv) + if (vnc_port != -1) + grd_settings_override_vnc_port (settings, vnc_port); + + grd_settings_override_max_parallel_connections (settings, + max_parallel_connections); - - return g_application_run (app, argc, argv); ++ + return g_application_run (G_APPLICATION (daemon), argc, argv); } +diff --git a/src/grd-rdp-server.c b/src/grd-rdp-server.c +index 207d9e2d..b4952935 100644 +--- a/src/grd-rdp-server.c ++++ b/src/grd-rdp-server.c +@@ -491,11 +491,14 @@ grd_rdp_server_dispose (GObject *object) + } + + static void +-grd_rdp_server_init (GrdRdpServer *rdp_server) ++grd_rdp_server_constructed (GObject *object) + { +- rdp_server->throttler = grd_throttler_new (grd_throttler_limits_new (), +- allow_connection_cb, +- rdp_server); ++ GrdRdpServer *rdp_server = GRD_RDP_SERVER (object); ++ ++ rdp_server->throttler = ++ grd_throttler_new (grd_throttler_limits_new (rdp_server->context), ++ allow_connection_cb, ++ rdp_server); + + rdp_server->pending_binding_attempts = RDP_SERVER_N_BINDING_ATTEMPTS; + +@@ -506,6 +509,13 @@ grd_rdp_server_init (GrdRdpServer *rdp_server) + * Run the primitives benchmark here to save time, when initializing a session + */ + primitives_get (); ++ ++ G_OBJECT_CLASS (grd_rdp_server_parent_class)->constructed (object); ++} ++ ++static void ++grd_rdp_server_init (GrdRdpServer *rdp_server) ++{ + } + + static void +@@ -516,6 +526,7 @@ grd_rdp_server_class_init (GrdRdpServerClass *klass) + object_class->set_property = grd_rdp_server_set_property; + object_class->get_property = grd_rdp_server_get_property; + object_class->dispose = grd_rdp_server_dispose; ++ object_class->constructed = grd_rdp_server_constructed; + + g_object_class_install_property (object_class, + PROP_CONTEXT, diff --git a/src/grd-settings.c b/src/grd-settings.c -index 7324310b..52cb1702 100644 +index f3475010..0720fcc4 100644 --- a/src/grd-settings.c +++ b/src/grd-settings.c -@@ -50,6 +50,8 @@ struct _GrdSettings - int port; +@@ -87,6 +87,8 @@ typedef struct _GrdSettingsPrivate + GrdVncAuthMethod auth_method; GrdVncEncryption encryption; } vnc; + + int max_parallel_connections; - }; + } GrdSettingsPrivate; - G_DEFINE_TYPE (GrdSettings, grd_settings, G_TYPE_OBJECT) -@@ -75,6 +77,19 @@ grd_settings_get_vnc_port (GrdSettings *settings) - return settings->vnc.port; + G_DEFINE_TYPE_WITH_PRIVATE (GrdSettings, grd_settings, G_TYPE_OBJECT) +@@ -103,6 +105,23 @@ grd_settings_get_runtime_mode (GrdSettings *settings) + return priv->runtime_mode; } +void +grd_settings_override_max_parallel_connections (GrdSettings *settings, + int max_parallel_connections) +{ -+ settings->max_parallel_connections = max_parallel_connections; ++ GrdSettingsPrivate *priv = grd_settings_get_instance_private (settings); ++ ++ priv->max_parallel_connections = max_parallel_connections; +} + +int +grd_settings_get_max_parallel_connections (GrdSettings *settings) +{ -+ return settings->max_parallel_connections; ++ GrdSettingsPrivate *priv = grd_settings_get_instance_private (settings); ++ ++ return priv->max_parallel_connections; +} + void - grd_settings_override_vnc_port (GrdSettings *settings, + grd_settings_override_rdp_port (GrdSettings *settings, int port) diff --git a/src/grd-settings.h b/src/grd-settings.h -index 0575ec1e..999581f4 100644 +index 547b1417..5abf8e4e 100644 --- a/src/grd-settings.h +++ b/src/grd-settings.h -@@ -35,6 +35,11 @@ const SecretSchema * cc_grd_vnc_password_get_schema (void); +@@ -38,6 +38,11 @@ struct _GrdSettingsClass - int grd_settings_get_vnc_port (GrdSettings *settings); + GrdRuntimeMode grd_settings_get_runtime_mode (GrdSettings *settings); +void grd_settings_override_max_parallel_connections (GrdSettings *settings, + int max_parallel_connections); + +int grd_settings_get_max_parallel_connections (GrdSettings *settings); + - void grd_settings_override_vnc_port (GrdSettings *settings, + void grd_settings_override_rdp_port (GrdSettings *settings, int port); diff --git a/src/grd-throttler.c b/src/grd-throttler.c @@ -1309,18 +1660,18 @@ index 9e72b8f1..a9554202 100644 GrdThrottler * grd_throttler_new (GrdThrottlerLimits *limits, diff --git a/src/grd-vnc-server.c b/src/grd-vnc-server.c -index f7240d37..bddc6909 100644 +index fc5020f0..705ed416 100644 --- a/src/grd-vnc-server.c +++ b/src/grd-vnc-server.c -@@ -280,6 +280,7 @@ grd_vnc_server_constructed (GObject *object) +@@ -298,6 +298,7 @@ grd_vnc_server_constructed (GObject *object) { GrdVncServer *vnc_server = GRD_VNC_SERVER (object); GrdSettings *settings = grd_context_get_settings (vnc_server->context); + GrdThrottlerLimits *limits; - if (grd_context_get_debug_flags (vnc_server->context) & GRD_DEBUG_VNC) + if (grd_get_debug_flags () & GRD_DEBUG_VNC) rfbLogEnable (1); -@@ -291,21 +292,21 @@ grd_vnc_server_constructed (GObject *object) +@@ -309,21 +310,20 @@ grd_vnc_server_constructed (GObject *object) vnc_server); sync_encryption_settings (vnc_server); @@ -1331,9 +1682,9 @@ index f7240d37..bddc6909 100644 -grd_vnc_server_init (GrdVncServer *vnc_server) -{ - GrdThrottlerLimits *limits; -+ limits = grd_throttler_limits_new (vnc_server->context); - +- - limits = grd_throttler_limits_new (); ++ limits = grd_throttler_limits_new (vnc_server->context); /* TODO: Add the rfbScreen instance to GrdVncServer to support multiple * sessions. */ grd_throttler_limits_set_max_global_connections (limits, 1); diff --git a/gnome-remote-desktop.spec b/gnome-remote-desktop.spec new file mode 100644 index 0000000..dbca173 --- /dev/null +++ b/gnome-remote-desktop.spec @@ -0,0 +1,392 @@ +%global systemd_unit_handover gnome-remote-desktop-handover.service +%global systemd_unit_headless gnome-remote-desktop-headless.service +%global systemd_unit_system gnome-remote-desktop.service +%global systemd_unit_user gnome-remote-desktop.service + +%global tarball_version %%(echo %{version} | tr '~' '.') + +%bcond rdp %[0%{?fedora} || 0%{?rhel} >= 10] +%bcond vnc %[0%{?fedora} || 0%{?rhel} < 10] + +%global libei_version 1.0.901 +%global pipewire_version 0.3.49 + +Name: gnome-remote-desktop +Version: 47.3 +Release: 2%{?dist} +Summary: GNOME Remote Desktop screen share service + +License: GPL-2.0-or-later +URL: https://gitlab.gnome.org/GNOME/gnome-remote-desktop +Source0: https://download.gnome.org/sources/%{name}/47/%{name}-%{tarball_version}.tar.xz + +# Adds encryption support (requires patched LibVNCServer) +Patch0: gnutls-anontls.patch +Patch1: connection-throttling.patch + +BuildRequires: asciidoc +BuildRequires: gcc +BuildRequires: meson >= 0.47.0 +BuildRequires: systemd-rpm-macros +BuildRequires: pkgconfig(cairo) +BuildRequires: pkgconfig(epoxy) +BuildRequires: pkgconfig(dbus-1) +BuildRequires: pkgconfig(ffnvcodec) +%if %{with rdp} +BuildRequires: pkgconfig(fdk-aac) +BuildRequires: pkgconfig(freerdp3) +BuildRequires: pkgconfig(fuse3) +BuildRequires: pkgconfig(opus) +BuildRequires: pkgconfig(polkit-gobject-1) +BuildRequires: pkgconfig(winpr3) +%endif +BuildRequires: pkgconfig(gbm) +BuildRequires: pkgconfig(glib-2.0) >= 2.68 +BuildRequires: pkgconfig(gio-unix-2.0) +BuildRequires: pkgconfig(gnutls) +BuildRequires: pkgconfig(gudev-1.0) +BuildRequires: pkgconfig(libdrm) +BuildRequires: pkgconfig(libei-1.0) >= %{libei_version} +BuildRequires: pkgconfig(libnotify) +BuildRequires: pkgconfig(libpipewire-0.3) +BuildRequires: pkgconfig(libsecret-1) +%if %{with vnc} +BuildRequires: pkgconfig(libvncserver) >= 0.9.11-7 +%endif +BuildRequires: pkgconfig(systemd) +BuildRequires: pkgconfig(xkbcommon) +BuildRequires: pkgconfig(tss2-esys) +BuildRequires: pkgconfig(tss2-mu) +BuildRequires: pkgconfig(tss2-rc) +BuildRequires: pkgconfig(tss2-tctildr) + +Requires: libei%{?_isa} >= %{libei_version} +Requires: pipewire%{?_isa} >= %{pipewire_version} + +Obsoletes: vino < 3.22.0-21 + +%description +GNOME Remote Desktop is a remote desktop and screen sharing service for the +GNOME desktop environment. + + +%prep +%autosetup -p1 -n %{name}-%{tarball_version} + + +%build +%meson \ +%if %{with rdp} + -Drdp=true \ +%else + -Drdp=false \ +%endif +%if %{with vnc} + -Dvnc=true \ +%else + -Dvnc=false \ +%endif + -Dsystemd=true \ + -Dtests=false +%meson_build + + +%install +%meson_install + +%find_lang %{name} + + +%post +%systemd_post %{systemd_unit_system} +%systemd_user_post %{systemd_unit_handover} +%systemd_user_post %{systemd_unit_headless} +%systemd_user_post %{systemd_unit_user} + + +%preun +%systemd_preun %{systemd_unit_system} +%systemd_user_preun %{systemd_unit_handover} +%systemd_user_preun %{systemd_unit_headless} +%systemd_user_preun %{systemd_unit_user} + + +%postun +%systemd_postun_with_restart %{systemd_unit_system} +%systemd_user_postun_with_restart %{systemd_unit_handover} +%systemd_user_postun_with_restart %{systemd_unit_headless} +%systemd_user_postun_with_restart %{systemd_unit_user} + + +%files -f %{name}.lang +%license COPYING +%doc README.md +%{_bindir}/grdctl +%{_libexecdir}/gnome-remote-desktop-daemon +%{_libexecdir}/gnome-remote-desktop-enable-service +%{_libexecdir}/gnome-remote-desktop-configuration-daemon +%{_userunitdir}/%{systemd_unit_user} +%{_userunitdir}/%{systemd_unit_headless} +%{_userunitdir}/%{systemd_unit_handover} +%{_unitdir}/%{systemd_unit_system} +%{_unitdir}/gnome-remote-desktop-configuration.service +%{_datadir}/applications/org.gnome.RemoteDesktop.Handover.desktop +%{_datadir}/dbus-1/system-services/org.gnome.RemoteDesktop.Configuration.service +%{_datadir}/dbus-1/system.d/org.gnome.RemoteDesktop.conf +%{_datadir}/glib-2.0/schemas/org.gnome.desktop.remote-desktop.gschema.xml +%{_datadir}/glib-2.0/schemas/org.gnome.desktop.remote-desktop.enums.xml +%{_datadir}/polkit-1/actions/org.gnome.remotedesktop.configure-system-daemon.policy +%{_datadir}/polkit-1/actions/org.gnome.remotedesktop.enable-system-daemon.policy +%{_datadir}/polkit-1/rules.d/20-gnome-remote-desktop.rules +%{_sysusersdir}/gnome-remote-desktop-sysusers.conf +%{_tmpfilesdir}/gnome-remote-desktop-tmpfiles.conf + +%if %{with rdp} +%{_datadir}/gnome-remote-desktop/ +%endif +%{_mandir}/man1/grdctl.1* + + +%changelog +* Thu Jul 03 2025 Jonas Ådahl - 47.3-2 +- Backport connection throttling + Resolves: RHEL-92787 + +* Fri Jan 24 2025 Jiri Koten - 47.3-1 +- Update to 47.3 + Resolves: RHEL-74559 + +* Tue Oct 29 2024 Troy Dawson - 47.alpha-2 +- Bump release for October 2024 mass rebuild: + Resolves: RHEL-64018 + +* Mon Jul 22 2024 Jonas Ådahl - 47~alpha-1 +- Update to 47.alpha + Resolves: RHEL-50079 + +* Mon Jun 24 2024 Troy Dawson - 46.2-2 +- Bump release for June 2024 mass rebuild + +* Thu May 23 2024 Nieves Montero - 46.2-1 +- Update to 46.2 + +* Thu Apr 18 2024 David King - 46.1-1 +- Update to 46.1 + +* Thu Mar 28 2024 Adam Williamson - 46.0-2 +- Correct systemd macros + +* Wed Jan 24 2024 Fedora Release Engineering - 45.1-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Fri Jan 19 2024 Fedora Release Engineering - 45.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Fri Nov 24 2023 Yaakov Selkowitz - 45.1-2 +- Disable VNC in RHEL 10+ + +* Sun Oct 22 2023 Kalev Lember - 45.1-1 +- Update to 45.1 + +* Sat Oct 21 2023 Kalev Lember - 45.0-1 +- Update to 45.0 + +* Tue Sep 05 2023 Kalev Lember - 45.rc-1 +- Update to 45.rc + +* Fri Aug 11 2023 Kalev Lember - 45.beta-1 +- Update to 45.beta + +* Wed Jul 19 2023 Fedora Release Engineering - 45.alpha-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild + +* Wed Jul 05 2023 Jonas Ådahl - 45~alpha-1 +- Update to 45.alpha + +* Wed May 31 2023 Kalev Lember - 44.2-1 +- Update to 44.2 + +* Mon Apr 24 2023 David King - 44.1-1 +- Update to 44.1 + +* Sun Mar 19 2023 David King - 44.0-1 +- Update to 44.0 + +* Thu Mar 16 2023 Jonas Ådahl - 44~rc-2 +- Enable RDP in ELN + +* Sun Mar 05 2023 David King - 44~rc-1 +- Update to 44.rc + +* Mon Feb 06 2023 David King - 44~alpha-1 +- Update to 44.alpha + +* Thu Jan 19 2023 Fedora Release Engineering - 43.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + +* Thu Dec 08 2022 David King - 43.2-1 +- Update to 43.2 + +* Tue Nov 08 2022 Stephen Gallagher - 43.1-2 +- Fix build on RHEL 9+/ELN + +* Thu Oct 27 2022 David King - 43.1-1 +- Update to 43.1 + +* Tue Sep 20 2022 Jonas Ådahl - 43.0 +- Update to 43.0 + +* Thu Aug 18 2022 Jonas Ådahl - 43~beta-4 +- Drop dependency on tpm2-abrmd + +* Tue Aug 16 2022 Kalev Lember - 43~beta-3 +- Avoid manual requires on tss2* and rely on automatic soname deps instead + +* Mon Aug 15 2022 Simone Caronni - 43~beta-2 +- Rebuild for updated FreeRDP. + +* Thu Aug 11 2022 Jonas Ådahl - 43~beta +- Update to 43.beta + +* Fri Jul 29 2022 Tomas Popela - 43~alpha-2 +- FreeRDP is built without server support in RHEL and ELN so we should disable + the RDP there + +* Thu Jul 28 2022 Jonas Ådahl - 43~alpha +- Update to 43.alpha + +* Thu Jul 21 2022 Fedora Release Engineering - 42.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + +* Thu Jul 07 2022 David King - 42.3-1 +- Update to 43.3 (#2091415) + +* Sun May 29 2022 David King - 42.2-1 +- Update to 42.2 + +* Wed May 11 2022 David King - 42.1.1-1 +- Update to 42.1.1 (#2061546) + +* Wed Apr 27 2022 David King - 42.1-2 +- Fix isa macro in Requires + +* Tue Apr 26 2022 David King - 42.1-1 +- Update to 42.1 (#2061546) + +* Mon Mar 21 2022 Jonas Ådahl - 42.0 +- Update to 42.0 + +* Mon Mar 14 2022 Jonas Ådahl - 42~rc-1 +- Update to 42.rc + +* Wed Feb 16 2022 Jonas Ådahl - 42~beta-1 +- Update to 42.beta + +* Thu Jan 20 2022 Fedora Release Engineering - 41.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + +* Wed Dec 08 2021 Jonas Ådahl - 41.2-1 +- Update to 41.2 + +* Mon Nov 01 2021 Kalev Lember - 41.1-1 +- Update to 41.1 + +* Mon Sep 20 2021 Kalev Lember - 41.0-1 +- Update to 41.0 + +* Tue Sep 07 2021 Jonas Ådahl - 41~rc-1 +- Bump to 41.rc + +* Wed Aug 04 2021 Kalev Lember - 40.1-3 +- Avoid systemd_requires as per updated packaging guidelines + +* Thu Jul 22 2021 Fedora Release Engineering - 40.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + +* Mon May 03 2021 Jonas Ådahl - 40.1-1 +- Bump to 40.1 + +* Thu Apr 15 2021 Simone Caronni - 40.0-2 +- Rebuild for updated FreeRDP. + +* Mon Mar 22 2021 Kalev Lember - 40.0-1 +- Update to 40.0 + +* Thu Mar 18 2021 Michael Catanzaro - 40.0~rc-2 +- Add Obsoletes: vino + +* Mon Mar 15 2021 Kalev Lember - 40.0~rc-1 +- Update to 40.rc + +* Thu Mar 04 2021 Jonas Ådahl - 40.0~beta-1 +- Bump to 40.beta + +* Tue Jan 26 2021 Fedora Release Engineering - 0.1.9-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Mon Sep 14 2020 Jonas Ådahl - 0.1.9-2 +- Copy using the right destination stride + +* Mon Sep 14 2020 Jonas Ådahl - 0.1.9-1 +- Update to 0.1.9 +- Backport race condition crash fix +- Rebase anon-tls patches + +* Thu Aug 27 2020 Ray Strode - 0.1.8-3 +- Fix crash + Related: #1844993 + +* Mon Jun 1 2020 Felipe Borges - 0.1.8-2 +- Fix black screen issue in remote connections on Wayland + +* Wed Mar 11 2020 Jonas Ådahl - 0.1.8-1 +- Update to 0.1.8 + +* Tue Jan 28 2020 Fedora Release Engineering - 0.1.7-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Thu Jul 25 2019 Fedora Release Engineering - 0.1.7-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Mon Mar 4 2019 Jonas Ådahl - 0.1.7-1 +- Update to 0.1.7 + +* Thu Jan 31 2019 Fedora Release Engineering - 0.1.6-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Tue Oct 2 2018 Jonas Ådahl - 0.1.6-2 +- Don't crash when PipeWire disconnects (rhbz#1632781) + +* Tue Aug 7 2018 Jonas Ådahl - 0.1.6 +- Update to 0.1.6 +- Apply ANON-TLS patch +- Depend on pipewire 0.2.2 + +* Fri Jul 13 2018 Fedora Release Engineering - 0.1.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Wed May 30 2018 Jonas Ådahl - 0.1.4-1 +- Update to new version + +* Fri Feb 09 2018 Igor Gnatenko - 0.1.2-5 +- Escape macros in %%changelog + +* Wed Feb 07 2018 Fedora Release Engineering - 0.1.2-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Tue Aug 29 2017 Jonas Ådahl - 0.1.2-3 +- Use %%autosetup +- Install licence file + +* Tue Aug 22 2017 Jonas Ådahl - 0.1.2-2 +- Remove gschema compilation step as that had been deprecated + +* Mon Aug 21 2017 Jonas Ådahl - 0.1.2-1 +- Update to 0.1.2 +- Changed tabs to spaces +- Added systemd user macros +- Install to correct systemd user unit directory +- Compile gsettings schemas after install and uninstall + +* Mon Aug 21 2017 Jonas Ådahl - 0.1.1-1 +- First packaged version diff --git a/SOURCES/anon-tls-support.patch b/gnutls-anontls.patch similarity index 78% rename from SOURCES/anon-tls-support.patch rename to gnutls-anontls.patch index f165f69..56d91f6 100644 --- a/SOURCES/anon-tls-support.patch +++ b/gnutls-anontls.patch @@ -1,4 +1,4 @@ -From 10843a1f3edffbb475c01835451d39ebe6153e44 Mon Sep 17 00:00:00 2001 +From 0e754e3a90f486c031da535656584673016107a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Thu, 14 Jun 2018 12:21:37 +0200 Subject: [PATCH 1/7] vnc: Add anonymous TLS encryption support @@ -11,36 +11,36 @@ VNC connection. --- meson.build | 1 + src/grd-enums.h | 6 + - src/grd-session-vnc.c | 98 +++- - src/grd-session-vnc.h | 15 + - src/grd-settings.c | 28 ++ - src/grd-settings.h | 2 + - src/grd-vnc-server.c | 45 ++ + src/grd-session-vnc.c | 120 ++++- + src/grd-session-vnc.h | 17 + + src/grd-settings-user.c | 3 + + src/grd-settings.c | 18 + + src/grd-vnc-server.c | 49 ++ src/grd-vnc-tls.c | 444 ++++++++++++++++++ src/grd-vnc-tls.h | 28 ++ - src/meson.build | 5 +- + src/meson.build | 3 + ...nome.desktop.remote-desktop.gschema.xml.in | 10 + - 11 files changed, 666 insertions(+), 16 deletions(-) + 11 files changed, 673 insertions(+), 26 deletions(-) create mode 100644 src/grd-vnc-tls.c create mode 100644 src/grd-vnc-tls.h diff --git a/meson.build b/meson.build -index 1c96849..a24acfd 100644 +index 995863ce..40733a6e 100644 --- a/meson.build +++ b/meson.build -@@ -15,6 +15,7 @@ libvncserver_dep = dependency('libvncserver') - libvncclient_dep = dependency('libvncclient') - libsecret_dep = dependency('libsecret-1') - libnotify_dep = dependency('libnotify') -+gnutls_dep = dependency('gnutls') +@@ -62,6 +62,7 @@ endif + if have_vnc + libvncclient_dep = dependency('libvncclient') + libvncserver_dep = dependency('libvncserver') ++ gnutls_dep = dependency('gnutls') + endif - cdata = configuration_data() - cdata.set_quoted('GETTEXT_PACKAGE', 'gnome-remote-desktop') + prefix = get_option('prefix') diff --git a/src/grd-enums.h b/src/grd-enums.h -index ffab821..4333863 100644 +index 028bdf9a..47a1d921 100644 --- a/src/grd-enums.h +++ b/src/grd-enums.h -@@ -27,4 +27,10 @@ typedef enum +@@ -33,6 +33,12 @@ typedef enum GRD_VNC_AUTH_METHOD_PASSWORD } GrdVncAuthMethod; @@ -50,12 +50,14 @@ index ffab821..4333863 100644 + GRD_VNC_ENCRYPTION_TLS_ANON = 1 << 1, +} GrdVncEncryption; + - #endif /* GRD_ENUMS_H */ + typedef enum + { + GRD_VNC_SCREEN_SHARE_MODE_MIRROR_PRIMARY, diff --git a/src/grd-session-vnc.c b/src/grd-session-vnc.c -index 1f3f0e2..0cc2ea2 100644 +index 0ca76e89..e13ac013 100644 --- a/src/grd-session-vnc.c +++ b/src/grd-session-vnc.c -@@ -44,7 +44,9 @@ struct _GrdSessionVnc +@@ -46,7 +46,9 @@ struct _GrdSessionVnc { GrdSession parent; @@ -65,7 +67,7 @@ index 1f3f0e2..0cc2ea2 100644 GSource *source; rfbScreenInfoPtr rfb_screen; rfbClientPtr rfb_client; -@@ -505,12 +507,30 @@ check_rfb_password (rfbClientPtr rfb_client, +@@ -608,6 +610,12 @@ check_rfb_password (rfbClientPtr rfb_client, } } @@ -76,9 +78,10 @@ index 1f3f0e2..0cc2ea2 100644 +} + int - grd_session_vnc_get_framebuffer_stride (GrdSessionVnc *session_vnc) - { - return session_vnc->rfb_screen->paddedWidthInBytes; + grd_session_vnc_get_stride_for_width (GrdSessionVnc *session_vnc, + int width) +@@ -615,6 +623,18 @@ grd_session_vnc_get_stride_for_width (GrdSessionVnc *session_vnc, + return width * BGRX_BYTES_PER_PIXEL; } +rfbClientPtr @@ -96,7 +99,7 @@ index 1f3f0e2..0cc2ea2 100644 static void init_vnc_session (GrdSessionVnc *session_vnc) { -@@ -551,33 +571,74 @@ init_vnc_session (GrdSessionVnc *session_vnc) +@@ -689,44 +709,85 @@ init_vnc_session (GrdSessionVnc *session_vnc) rfbProcessEvents (rfb_screen, 0); } @@ -131,6 +134,17 @@ index 1f3f0e2..0cc2ea2 100644 + session_vnc->pending_framebuffer_width, + session_vnc->pending_framebuffer_height); + session_vnc->pending_framebuffer_resize = FALSE; ++ ++ /** ++ * This is a workaround. libvncserver is unable to handle clipboard ++ * changes early and either disconnects the client or crashes g-r-d ++ * if it receives rfbSendServerCutText too early altough the ++ * authentification process is already done. ++ * Doing this after resizing the framebuffer, seems to work fine, ++ * so enable the clipboard here and not when the remote desktop ++ * session proxy is acquired. ++ */ ++ grd_clipboard_vnc_maybe_enable_clipboard (session_vnc->clipboard_vnc); + } + } + @@ -172,6 +186,17 @@ index 1f3f0e2..0cc2ea2 100644 - session_vnc->pending_framebuffer_width, - session_vnc->pending_framebuffer_height); - session_vnc->pending_framebuffer_resize = FALSE; +- +- /** +- * This is a workaround. libvncserver is unable to handle clipboard +- * changes early and either disconnects the client or crashes g-r-d +- * if it receives rfbSendServerCutText too early altough the +- * authentification process is already done. +- * Doing this after resizing the framebuffer, seems to work fine, +- * so enable the clipboard here and not when the remote desktop +- * session proxy is acquired. +- */ +- grd_clipboard_vnc_maybe_enable_clipboard (session_vnc->clipboard_vnc); - } + grd_session_stop (session); } @@ -185,7 +210,7 @@ index 1f3f0e2..0cc2ea2 100644 } return G_SOURCE_CONTINUE; -@@ -590,7 +651,10 @@ grd_session_vnc_attach_source (GrdSessionVnc *session_vnc) +@@ -739,7 +800,10 @@ grd_session_vnc_attach_source (GrdSessionVnc *session_vnc) socket = g_socket_connection_get_socket (session_vnc->connection); session_vnc->source = g_socket_create_source (socket, @@ -197,18 +222,23 @@ index 1f3f0e2..0cc2ea2 100644 NULL); g_source_set_callback (session_vnc->source, (GSourceFunc) handle_socket_data, -@@ -616,8 +680,10 @@ grd_session_vnc_new (GrdVncServer *vnc_server, +@@ -780,6 +844,7 @@ grd_session_vnc_new (GrdVncServer *vnc_server, "context", context, NULL); + session_vnc->vnc_server = vnc_server; session_vnc->connection = g_object_ref (connection); + settings = grd_context_get_settings (context); +@@ -792,6 +857,7 @@ grd_session_vnc_new (GrdVncServer *vnc_server, + G_CALLBACK (on_view_only_changed), + session_vnc); + + grd_session_vnc_grab_socket (session_vnc, vnc_socket_grab_func); grd_session_vnc_attach_source (session_vnc); init_vnc_session (session_vnc); -@@ -632,6 +698,8 @@ grd_session_vnc_dispose (GObject *object) +@@ -806,6 +872,8 @@ grd_session_vnc_dispose (GObject *object) g_assert (!session_vnc->rfb_screen); @@ -218,12 +248,12 @@ index 1f3f0e2..0cc2ea2 100644 G_OBJECT_CLASS (grd_session_vnc_parent_class)->dispose (object); diff --git a/src/grd-session-vnc.h b/src/grd-session-vnc.h -index 14b5d12..46a8579 100644 +index be79cf4a..ffc8d27a 100644 --- a/src/grd-session-vnc.h +++ b/src/grd-session-vnc.h -@@ -36,6 +36,9 @@ G_DECLARE_FINAL_TYPE (GrdSessionVnc, +@@ -37,6 +37,9 @@ G_DECLARE_FINAL_TYPE (GrdSessionVnc, GRD, SESSION_VNC, - GrdSession); + GrdSession) +typedef gboolean (* GrdVncSocketGrabFunc) (GrdSessionVnc *session_vnc, + GError **error); @@ -231,13 +261,15 @@ index 14b5d12..46a8579 100644 GrdSessionVnc *grd_session_vnc_new (GrdVncServer *vnc_server, GSocketConnection *connection); -@@ -53,6 +56,18 @@ void grd_session_vnc_move_cursor (GrdSessionVnc *session_vnc, - int x, - int y); +@@ -63,6 +66,20 @@ void grd_session_vnc_set_client_clipboard_text (GrdSessionVnc *session_vnc, + int grd_session_vnc_get_stride_for_width (GrdSessionVnc *session_vnc, + int width); +int grd_session_vnc_get_fd (GrdSessionVnc *session_vnc); + - int grd_session_vnc_get_framebuffer_stride (GrdSessionVnc *session_vnc); ++int grd_session_vnc_get_framebuffer_stride (GrdSessionVnc *session_vnc); ++ + gboolean grd_session_vnc_is_client_gone (GrdSessionVnc *session_vnc); +rfbClientPtr grd_session_vnc_get_rfb_client (GrdSessionVnc *session_vnc); + @@ -250,94 +282,80 @@ index 14b5d12..46a8579 100644 +GrdVncServer * grd_session_vnc_get_vnc_server (GrdSessionVnc *session_vnc); + #endif /* GRD_SESSION_VNC_H */ +diff --git a/src/grd-settings-user.c b/src/grd-settings-user.c +index 20b81a94..34115078 100644 +--- a/src/grd-settings-user.c ++++ b/src/grd-settings-user.c +@@ -79,6 +79,9 @@ grd_settings_user_constructed (GObject *object) + g_settings_bind (settings->vnc_settings, "auth-method", + settings, "vnc-auth-method", + G_SETTINGS_BIND_DEFAULT); ++ g_settings_bind (settings->vnc_settings, "encryption", ++ settings, "vnc-encryption", ++ G_SETTINGS_BIND_DEFAULT); + + switch (grd_settings_get_runtime_mode (GRD_SETTINGS (settings))) + { diff --git a/src/grd-settings.c b/src/grd-settings.c -index bdf8211..7324310 100644 +index fba1d714..f3475010 100644 --- a/src/grd-settings.c +++ b/src/grd-settings.c -@@ -48,6 +48,7 @@ struct _GrdSettings - gboolean view_only; - GrdVncAuthMethod auth_method; - int port; -+ GrdVncEncryption encryption; - } vnc; +@@ -58,6 +58,7 @@ enum + PROP_RDP_SERVER_CERT_PATH, + PROP_RDP_SERVER_KEY_PATH, + PROP_VNC_AUTH_METHOD, ++ PROP_VNC_ENCRYPTION, }; -@@ -120,6 +121,12 @@ grd_settings_get_vnc_auth_method (GrdSettings *settings) - return settings->vnc.auth_method; - } + typedef struct _GrdSettingsPrivate +@@ -84,6 +85,7 @@ typedef struct _GrdSettingsPrivate + gboolean view_only; + GrdVncScreenShareMode screen_share_mode; + GrdVncAuthMethod auth_method; ++ GrdVncEncryption encryption; + } vnc; + } GrdSettingsPrivate; -+GrdVncEncryption -+grd_settings_get_vnc_encryption (GrdSettings *settings) -+{ -+ return settings->vnc.encryption; -+} -+ - static void - update_vnc_view_only (GrdSettings *settings) - { -@@ -134,6 +141,13 @@ update_vnc_auth_method (GrdSettings *settings) - "auth-method"); - } - -+static void -+update_vnc_encryption (GrdSettings *settings) -+{ -+ settings->vnc.encryption = g_settings_get_flags (settings->vnc.settings, -+ "encryption"); -+} -+ - static void - on_vnc_settings_changed (GSettings *vnc_settings, - const char *key, -@@ -149,6 +163,11 @@ on_vnc_settings_changed (GSettings *vnc_settings, - update_vnc_auth_method (settings); - g_signal_emit (settings, signals[VNC_AUTH_METHOD_CHANGED], 0); +@@ -425,6 +427,9 @@ grd_settings_get_property (GObject *object, + else + g_value_set_enum (value, priv->vnc.auth_method); + break; ++ case PROP_VNC_ENCRYPTION: ++ g_value_set_flags (value, priv->vnc.encryption); ++ break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } -+ else if (strcmp (key, "encryption") == 0) -+ { -+ update_vnc_encryption (settings); -+ g_signal_emit (settings, signals[VNC_ENCRYPTION_CHANGED], 0); -+ } +@@ -562,6 +567,9 @@ grd_settings_set_property (GObject *object, + case PROP_VNC_AUTH_METHOD: + priv->vnc.auth_method = g_value_get_enum (value); + break; ++ case PROP_VNC_ENCRYPTION: ++ priv->vnc.encryption = g_value_get_flags (value); ++ break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +@@ -743,4 +751,14 @@ grd_settings_class_init (GrdSettingsClass *klass) + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); ++ g_object_class_install_property (object_class, ++ PROP_VNC_ENCRYPTION, ++ g_param_spec_flags ("vnc-encryption", ++ "vnc encryption", ++ "vnc encryption", ++ GRD_TYPE_VNC_ENCRYPTION, ++ GRD_VNC_ENCRYPTION_TLS_ANON, ++ G_PARAM_READWRITE | ++ G_PARAM_CONSTRUCT | ++ G_PARAM_STATIC_STRINGS)); } - - static void -@@ -172,6 +191,8 @@ grd_settings_init (GrdSettings *settings) - update_vnc_auth_method (settings); - - settings->vnc.port = GRD_VNC_SERVER_PORT; -+ -+ update_vnc_encryption (settings); - } - - static void -@@ -195,4 +216,11 @@ grd_settings_class_init (GrdSettingsClass *klass) - 0, - NULL, NULL, NULL, - G_TYPE_NONE, 0); -+ signals[VNC_ENCRYPTION_CHANGED] = -+ g_signal_new ("vnc-encryption-changed", -+ G_TYPE_FROM_CLASS (klass), -+ G_SIGNAL_RUN_LAST, -+ 0, -+ NULL, NULL, NULL, -+ G_TYPE_NONE, 0); - } -diff --git a/src/grd-settings.h b/src/grd-settings.h -index e4e0c09..0575ec1 100644 ---- a/src/grd-settings.h -+++ b/src/grd-settings.h -@@ -45,4 +45,6 @@ gboolean grd_settings_get_vnc_view_only (GrdSettings *settings); - - GrdVncAuthMethod grd_settings_get_vnc_auth_method (GrdSettings *settings); - -+GrdVncEncryption grd_settings_get_vnc_encryption (GrdSettings *settings); -+ - #endif /* GRD_SETTINGS_H */ diff --git a/src/grd-vnc-server.c b/src/grd-vnc-server.c -index a6d95cb..f9c68db 100644 +index 877272d2..59a13db5 100644 --- a/src/grd-vnc-server.c +++ b/src/grd-vnc-server.c -@@ -24,11 +24,13 @@ +@@ -24,6 +24,7 @@ #include "grd-vnc-server.h" @@ -345,13 +363,15 @@ index a6d95cb..f9c68db 100644 #include #include - #include "grd-context.h" +@@ -31,6 +32,7 @@ + #include "grd-debug.h" #include "grd-session-vnc.h" + #include "grd-utils.h" +#include "grd-vnc-tls.h" - enum -@@ -130,6 +132,43 @@ on_incoming (GSocketService *service, + { +@@ -130,6 +132,45 @@ on_incoming (GSocketService *service, return TRUE; } @@ -363,7 +383,9 @@ index a6d95cb..f9c68db 100644 + GrdVncEncryption encryption; + + tls_security_handler = grd_vnc_tls_get_security_handler (); -+ encryption = grd_settings_get_vnc_encryption (settings); ++ g_object_get (G_OBJECT (settings), ++ "vnc-encryption", &encryption, ++ NULL); + + if (encryption == (GRD_VNC_ENCRYPTION_NONE | GRD_VNC_ENCRYPTION_TLS_ANON)) + { @@ -395,18 +417,19 @@ index a6d95cb..f9c68db 100644 gboolean grd_vnc_server_start (GrdVncServer *vnc_server, GError **error) -@@ -220,12 +259,18 @@ static void +@@ -241,11 +282,19 @@ grd_vnc_server_dispose (GObject *object) + static void grd_vnc_server_constructed (GObject *object) { - GrdVncServer *vnc_server = GRD_VNC_SERVER (object); ++ GrdVncServer *vnc_server = GRD_VNC_SERVER (object); + GrdSettings *settings = grd_context_get_settings (vnc_server->context); - - if (grd_context_get_debug_flags (vnc_server->context) & GRD_DEBUG_VNC) ++ + if (grd_get_debug_flags () & GRD_DEBUG_VNC) rfbLogEnable (1); else rfbLogEnable (0); -+ g_signal_connect (settings, "vnc-encryption-changed", ++ g_signal_connect (settings, "notify::vnc-encryption", + G_CALLBACK (on_vnc_encryption_changed), + vnc_server); + sync_encryption_settings (vnc_server); @@ -416,7 +439,7 @@ index a6d95cb..f9c68db 100644 diff --git a/src/grd-vnc-tls.c b/src/grd-vnc-tls.c new file mode 100644 -index 0000000..ec4758e +index 00000000..ec4758e0 --- /dev/null +++ b/src/grd-vnc-tls.c @@ -0,0 +1,444 @@ @@ -866,7 +889,7 @@ index 0000000..ec4758e +} diff --git a/src/grd-vnc-tls.h b/src/grd-vnc-tls.h new file mode 100644 -index 0000000..135ef8c +index 00000000..135ef8c7 --- /dev/null +++ b/src/grd-vnc-tls.h @@ -0,0 +1,28 @@ @@ -899,34 +922,29 @@ index 0000000..135ef8c + +#endif /* GRD_VNC_TLS_H */ diff --git a/src/meson.build b/src/meson.build -index 0f76fab..9d2f1ce 100644 +index 914e2cc1..4e820c59 100644 --- a/src/meson.build +++ b/src/meson.build -@@ -21,6 +21,8 @@ daemon_sources = files([ - 'grd-vnc-pipewire-stream.h', - 'grd-vnc-server.c', - 'grd-vnc-server.h', -+ 'grd-vnc-tls.c', -+ 'grd-vnc-tls.h', - ]) +@@ -188,10 +188,13 @@ if have_vnc + 'grd-vnc-pipewire-stream.h', + 'grd-vnc-server.c', + 'grd-vnc-server.h', ++ 'grd-vnc-tls.c', ++ 'grd-vnc-tls.h', + ]) + + deps += [ + libvncserver_dep, ++ gnutls_dep, + ] + endif - gen_daemon_sources = [] -@@ -51,7 +53,8 @@ executable('gnome-remote-desktop-daemon', - pipewire_dep, - libvncserver_dep, - libsecret_dep, -- libnotify_dep], -+ libnotify_dep, -+ gnutls_dep], - include_directories: [configinc], - install: true, - install_dir: libexecdir) diff --git a/src/org.gnome.desktop.remote-desktop.gschema.xml.in b/src/org.gnome.desktop.remote-desktop.gschema.xml.in -index a5c2022..846e65b 100644 +index c3d583c1..8a736c82 100644 --- a/src/org.gnome.desktop.remote-desktop.gschema.xml.in +++ b/src/org.gnome.desktop.remote-desktop.gschema.xml.in -@@ -23,5 +23,15 @@ - * password - by requiring the remote client to provide a known password +@@ -148,5 +148,15 @@ + configuration updates. + @@ -942,10 +960,10 @@ index a5c2022..846e65b 100644 -- -2.26.2 +2.44.0 -From aa54aeb43938250a4d27a99e62eb5628d3b55076 Mon Sep 17 00:00:00 2001 +From 6e5f6deab459acdd1e7785ab6975932f2815548f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 27 Nov 2019 11:02:09 +0100 Subject: [PATCH 2/7] session-vnc: Add paused/resumed signals @@ -958,10 +976,10 @@ out-of-socket source. 1 file changed, 65 insertions(+), 7 deletions(-) diff --git a/src/grd-session-vnc.c b/src/grd-session-vnc.c -index 0cc2ea2..076e25f 100644 +index e13ac013..30820d7d 100644 --- a/src/grd-session-vnc.c +++ b/src/grd-session-vnc.c -@@ -40,14 +40,27 @@ +@@ -42,14 +42,27 @@ #define BGRX_SAMPLES_PER_PIXEL 3 #define BGRX_BYTES_PER_PIXEL 4 @@ -989,8 +1007,8 @@ index 0cc2ea2..076e25f 100644 rfbScreenInfoPtr rfb_screen; rfbClientPtr rfb_client; -@@ -73,7 +86,7 @@ struct _GrdSessionVnc - G_DEFINE_TYPE (GrdSessionVnc, grd_session_vnc, GRD_TYPE_SESSION); +@@ -81,7 +94,7 @@ struct _GrdSessionVnc + G_DEFINE_TYPE (GrdSessionVnc, grd_session_vnc, GRD_TYPE_SESSION) static void -grd_session_vnc_detach_source (GrdSessionVnc *session_vnc); @@ -998,7 +1016,7 @@ index 0cc2ea2..076e25f 100644 static gboolean close_session_idle (gpointer user_data); -@@ -212,7 +225,8 @@ handle_client_gone (rfbClientPtr rfb_client) +@@ -248,7 +261,8 @@ handle_client_gone (rfbClientPtr rfb_client) g_debug ("VNC client gone"); @@ -1006,18 +1024,18 @@ index 0cc2ea2..076e25f 100644 + grd_session_vnc_pause (session_vnc); + maybe_queue_close_session_idle (session_vnc); + session_vnc->rfb_client = NULL; } - -@@ -280,7 +294,7 @@ handle_new_client (rfbClientPtr rfb_client) - session_vnc->prompt_cancellable, - prompt_response_callback, - session_vnc); +@@ -338,7 +352,7 @@ handle_new_client (rfbClientPtr rfb_client) + { + case GRD_VNC_AUTH_METHOD_PROMPT: + show_sharing_desktop_prompt (session_vnc, rfb_client->host); - grd_session_vnc_detach_source (session_vnc); + grd_session_vnc_pause (session_vnc); return RFB_CLIENT_ON_HOLD; case GRD_VNC_AUTH_METHOD_PASSWORD: session_vnc->rfb_screen->passwordCheck = check_rfb_password; -@@ -498,7 +512,7 @@ check_rfb_password (rfbClientPtr rfb_client, +@@ -601,7 +615,7 @@ check_rfb_password (rfbClientPtr rfb_client, if (memcmp (challenge_encrypted, response_encrypted, len) == 0) { grd_session_start (GRD_SESSION (session_vnc)); @@ -1026,8 +1044,8 @@ index 0cc2ea2..076e25f 100644 return TRUE; } else -@@ -668,6 +682,36 @@ grd_session_vnc_detach_source (GrdSessionVnc *session_vnc) - g_clear_pointer (&session_vnc->source, g_source_destroy); +@@ -821,6 +835,36 @@ grd_session_vnc_detach_source (GrdSessionVnc *session_vnc) + g_clear_pointer (&session_vnc->source, g_source_unref); } +gboolean @@ -1060,10 +1078,10 @@ index 0cc2ea2..076e25f 100644 + g_signal_emit (session_vnc, signals[RESUMED], 0); +} + - GrdSessionVnc * - grd_session_vnc_new (GrdVncServer *vnc_server, - GSocketConnection *connection) -@@ -685,6 +729,7 @@ grd_session_vnc_new (GrdVncServer *vnc_server, + static void + on_view_only_changed (GrdSettings *settings, + GParamSpec *pspec, +@@ -859,6 +903,7 @@ grd_session_vnc_new (GrdVncServer *vnc_server, grd_session_vnc_grab_socket (session_vnc, vnc_socket_grab_func); grd_session_vnc_attach_source (session_vnc); @@ -1071,17 +1089,17 @@ index 0cc2ea2..076e25f 100644 init_vnc_session (session_vnc); -@@ -714,7 +759,7 @@ grd_session_vnc_stop (GrdSession *session) - - g_clear_object (&session_vnc->pipewire_stream); +@@ -893,7 +938,7 @@ grd_session_vnc_stop (GrdSession *session) + g_clear_object (&session_vnc->stream); + } - grd_session_vnc_detach_source (session_vnc); + grd_session_vnc_pause (session_vnc); g_clear_object (&session_vnc->connection); - g_clear_pointer (&session_vnc->rfb_screen->frameBuffer, g_free); -@@ -770,8 +815,8 @@ grd_session_vnc_stream_ready (GrdSession *session, - G_CALLBACK (on_pipwire_stream_closed), + g_clear_object (&session_vnc->clipboard_vnc); +@@ -984,8 +1029,8 @@ on_stream_ready (GrdStream *stream, + G_CALLBACK (on_pipewire_stream_closed), session_vnc); - if (!session_vnc->source) @@ -1091,10 +1109,10 @@ index 0cc2ea2..076e25f 100644 } static void -@@ -790,4 +835,17 @@ grd_session_vnc_class_init (GrdSessionVncClass *klass) - - session_class->stop = grd_session_vnc_stop; - session_class->stream_ready = grd_session_vnc_stream_ready; +@@ -1020,4 +1065,17 @@ grd_session_vnc_class_init (GrdSessionVncClass *klass) + session_class->remote_desktop_session_started = + grd_session_vnc_remote_desktop_session_started; + session_class->on_stream_created = grd_session_vnc_on_stream_created; + + signals[PAUSED] = g_signal_new ("paused", + G_TYPE_FROM_CLASS (klass), @@ -1110,10 +1128,10 @@ index 0cc2ea2..076e25f 100644 + G_TYPE_NONE, 0); } -- -2.26.2 +2.44.0 -From ed3d72cb8d08192831397903f0ba92f439751988 Mon Sep 17 00:00:00 2001 +From 00f4fdfc676361f5f71e6f6b346c11cb7088b836 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 27 Nov 2019 11:03:46 +0100 Subject: [PATCH 3/7] session-vnc: Add grd_session_vnc_dispatch() helper @@ -1126,10 +1144,10 @@ available that is not visible to the socket source. 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/grd-session-vnc.c b/src/grd-session-vnc.c -index 076e25f..8b8ce1b 100644 +index 30820d7d..3ee06f79 100644 --- a/src/grd-session-vnc.c +++ b/src/grd-session-vnc.c -@@ -622,6 +622,21 @@ vnc_socket_grab_func (GrdSessionVnc *session_vnc, +@@ -771,6 +771,21 @@ vnc_socket_grab_func (GrdSessionVnc *session_vnc, return TRUE; } @@ -1151,7 +1169,7 @@ index 076e25f..8b8ce1b 100644 static gboolean handle_socket_data (GSocket *socket, GIOCondition condition, -@@ -638,16 +653,7 @@ handle_socket_data (GSocket *socket, +@@ -787,16 +802,7 @@ handle_socket_data (GSocket *socket, } else if (condition & G_IO_IN) { @@ -1170,10 +1188,10 @@ index 076e25f..8b8ce1b 100644 else { diff --git a/src/grd-session-vnc.h b/src/grd-session-vnc.h -index 46a8579..910b00c 100644 +index ffc8d27a..a86d61d2 100644 --- a/src/grd-session-vnc.h +++ b/src/grd-session-vnc.h -@@ -68,6 +68,8 @@ void grd_session_vnc_grab_socket (GrdSessionVnc *session_vnc, +@@ -80,6 +80,8 @@ void grd_session_vnc_grab_socket (GrdSessionVnc *session_vnc, void grd_session_vnc_ungrab_socket (GrdSessionVnc *session_vnc, GrdVncSocketGrabFunc grab_func); @@ -1183,10 +1201,10 @@ index 46a8579..910b00c 100644 #endif /* GRD_SESSION_VNC_H */ -- -2.26.2 +2.44.0 -From 44e6bec84a86064a7b3abbcbbcd07ebb525aca9f Mon Sep 17 00:00:00 2001 +From 69efe6df5e9e8548c0241a612980af31f1dc5c5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 27 Nov 2019 11:05:13 +0100 Subject: [PATCH 4/7] vnc/tls: Add some logging @@ -1198,7 +1216,7 @@ protocol rather than the session itself. 1 file changed, 9 insertions(+) diff --git a/src/grd-vnc-tls.c b/src/grd-vnc-tls.c -index ec4758e..ac6c35f 100644 +index ec4758e0..ac6c35f6 100644 --- a/src/grd-vnc-tls.c +++ b/src/grd-vnc-tls.c @@ -67,6 +67,7 @@ grd_vnc_tls_context_new (void) @@ -1260,10 +1278,10 @@ index ec4758e..ac6c35f 100644 { g_warning ("TLS handshake failed: %s", error->message); -- -2.26.2 +2.44.0 -From fc07db3b6fafec47e02ff81f0f893dcaf64ba988 Mon Sep 17 00:00:00 2001 +From 2a11c4f47165b62409f4428b9de1bda59c6ebb2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 27 Nov 2019 11:07:40 +0100 Subject: [PATCH 5/7] vnc/tls: Dispatch also when data is pending outside of @@ -1276,14 +1294,14 @@ epoll(). Deal with this by adding a custom source that dispatches as long as there is data to read in those buffers. --- src/grd-session-vnc.h | 2 + - src/grd-vnc-tls.c | 92 ++++++++++++++++++++++++++++++++++++++++--- - 2 files changed, 88 insertions(+), 6 deletions(-) + src/grd-vnc-tls.c | 90 ++++++++++++++++++++++++++++++++++++++++--- + 2 files changed, 86 insertions(+), 6 deletions(-) diff --git a/src/grd-session-vnc.h b/src/grd-session-vnc.h -index 910b00c..294860e 100644 +index a86d61d2..5db388b0 100644 --- a/src/grd-session-vnc.h +++ b/src/grd-session-vnc.h -@@ -68,6 +68,8 @@ void grd_session_vnc_grab_socket (GrdSessionVnc *session_vnc, +@@ -80,6 +80,8 @@ void grd_session_vnc_grab_socket (GrdSessionVnc *session_vnc, void grd_session_vnc_ungrab_socket (GrdSessionVnc *session_vnc, GrdVncSocketGrabFunc grab_func); @@ -1293,7 +1311,7 @@ index 910b00c..294860e 100644 GrdVncServer * grd_session_vnc_get_vnc_server (GrdSessionVnc *session_vnc); diff --git a/src/grd-vnc-tls.c b/src/grd-vnc-tls.c -index ac6c35f..8f65225 100644 +index ac6c35f6..312b6b92 100644 --- a/src/grd-vnc-tls.c +++ b/src/grd-vnc-tls.c @@ -41,6 +41,12 @@ typedef enum _GrdTlsHandshakeState @@ -1318,12 +1336,7 @@ index ac6c35f..8f65225 100644 } GrdVncTlsSession; static gboolean -@@ -296,16 +304,14 @@ grd_vnc_tls_peek_at_socket (rfbClientPtr rfb_client, - peekable_len = MIN (len, tls_session->peek_buffer_len); - memcpy (buf, tls_session->peek_buffer, peekable_len); - -+ fprintf(stderr, ":::: %s:%d %s() - peeked %d bytes, can peek %d bytes\n", __FILE__, __LINE__, __func__, -+ peekable_len, tls_session->peek_buffer_len); +@@ -299,13 +307,9 @@ grd_vnc_tls_peek_at_socket (rfbClientPtr rfb_client, return peekable_len; } @@ -1339,7 +1352,7 @@ index ac6c35f..8f65225 100644 if (tls_session->peek_buffer_len > 0) return TRUE; -@@ -315,6 +321,16 @@ grd_vnc_tls_has_pending_on_socket (rfbClientPtr rfb_client) +@@ -315,6 +319,16 @@ grd_vnc_tls_has_pending_on_socket (rfbClientPtr rfb_client) return FALSE; } @@ -1356,7 +1369,7 @@ index ac6c35f..8f65225 100644 static int grd_vnc_tls_write_to_socket (rfbClientPtr rfb_client, const char *buf, -@@ -403,6 +419,62 @@ tls_handshake_grab_func (GrdSessionVnc *session_vnc, +@@ -403,6 +417,62 @@ tls_handshake_grab_func (GrdSessionVnc *session_vnc, return TRUE; } @@ -1419,7 +1432,7 @@ index ac6c35f..8f65225 100644 static void rfb_tls_security_handler (rfbClientPtr rfb_client) { -@@ -429,6 +501,14 @@ rfb_tls_security_handler (rfbClientPtr rfb_client) +@@ -429,6 +499,14 @@ rfb_tls_security_handler (rfbClientPtr rfb_client) rfb_client->hasPendingOnSocket = grd_vnc_tls_has_pending_on_socket; rfb_client->writeToSocket = grd_vnc_tls_write_to_socket; @@ -1435,10 +1448,10 @@ index ac6c35f..8f65225 100644 } -- -2.26.2 +2.44.0 -From c582baab12c1e2dd2b512329da42880c40993df6 Mon Sep 17 00:00:00 2001 +From 1ed580b541ab5c3b815d8e29cf3aa71f1de0b649 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 27 Nov 2019 16:48:00 +0100 Subject: [PATCH 6/7] session-vnc: Set our own password handling function up @@ -1457,10 +1470,10 @@ password prompt. 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/grd-session-vnc.c b/src/grd-session-vnc.c -index 8b8ce1b..a93a2e3 100644 +index 3ee06f79..6e118d88 100644 --- a/src/grd-session-vnc.c +++ b/src/grd-session-vnc.c -@@ -91,11 +91,6 @@ grd_session_vnc_pause (GrdSessionVnc *session_vnc); +@@ -99,11 +99,6 @@ grd_session_vnc_pause (GrdSessionVnc *session_vnc); static gboolean close_session_idle (gpointer user_data); @@ -1472,7 +1485,7 @@ index 8b8ce1b..a93a2e3 100644 static void swap_uint8 (uint8_t *a, uint8_t *b) -@@ -297,7 +292,6 @@ handle_new_client (rfbClientPtr rfb_client) +@@ -355,7 +350,6 @@ handle_new_client (rfbClientPtr rfb_client) grd_session_vnc_pause (session_vnc); return RFB_CLIENT_ON_HOLD; case GRD_VNC_AUTH_METHOD_PASSWORD: @@ -1480,9 +1493,9 @@ index 8b8ce1b..a93a2e3 100644 /* * authPasswdData needs to be non NULL in libvncserver to trigger * password authentication. -@@ -581,6 +575,8 @@ init_vnc_session (GrdSessionVnc *session_vnc) - rfb_screen->frameBuffer = g_malloc0 (screen_width * screen_height * 4); - memset (rfb_screen->frameBuffer, 0x1f, screen_width * screen_height * 4); +@@ -719,6 +713,8 @@ init_vnc_session (GrdSessionVnc *session_vnc) + session_vnc->monitor_config->connectors = connectors; + } + rfb_screen->passwordCheck = check_rfb_password; + @@ -1490,43 +1503,40 @@ index 8b8ce1b..a93a2e3 100644 rfbProcessEvents (rfb_screen, 0); } -- -2.26.2 +2.44.0 -From b7fc232ee5272b430f28c33ebaacd501ff63a4dc Mon Sep 17 00:00:00 2001 +From 9b7b729d9f945fcb2942c74d8ab7a9b62d6cf4bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= -Date: Wed, 27 Nov 2019 16:53:42 +0100 -Subject: [PATCH 7/7] vnc: Unregister previously set security handlers on init +Date: Mon, 12 Oct 2020 17:34:30 +0200 +Subject: [PATCH 7/7] vnc: Copy pixels using the right destination stride -When we're starting a session, we're going to handle a new client -connection. However, any previous client that was ever run on in a -previous session would still have their "security handler" registered, -as such is a global permanent change in libvncserver right now. +We're copying the pixels in a separate thread managed by PipeWire, and +in this thread, accessing the VNC framebuffer dimension and stride is +racy. Instead of fetching the dimension directly, pass the expected +width and get the stride it will eventually have. -To work around this, unregister all primary security handler (i.e. -'none' and 'password') when initializing the RFB screen. We'll set up -the preferred one when handling the new client. +Already before this patch, when the copied pixel end up on the main +thread and the dimension still doesn't match up, the frame will be +dropped. --- - src/grd-session-vnc.c | 6 ++++++ - 1 file changed, 6 insertions(+) + src/grd-session-vnc.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) -diff --git a/src/grd-session-vnc.c b/src/grd-session-vnc.c -index a93a2e3..9fcbb69 100644 ---- a/src/grd-session-vnc.c -+++ b/src/grd-session-vnc.c -@@ -555,6 +555,12 @@ init_vnc_session (GrdSessionVnc *session_vnc) - 8, 3, 4); - session_vnc->rfb_screen = rfb_screen; +diff --git a/src/grd-session-vnc.h b/src/grd-session-vnc.h +index 5db388b0..c4f4e8d4 100644 +--- a/src/grd-session-vnc.h ++++ b/src/grd-session-vnc.h +@@ -68,7 +68,8 @@ int grd_session_vnc_get_stride_for_width (GrdSessionVnc *session_vnc, -+ /* -+ * Unregister whatever security handler was used the last time; we'll set -+ * up new ones when authorizing the new client anyway. -+ */ -+ rfbUnregisterPrimarySecurityHandlers (); -+ - update_server_format (session_vnc); + int grd_session_vnc_get_fd (GrdSessionVnc *session_vnc); + +-int grd_session_vnc_get_framebuffer_stride (GrdSessionVnc *session_vnc); ++int grd_session_vnc_get_stride_for_width (GrdSessionVnc *session_vnc, ++ int width); + + gboolean grd_session_vnc_is_client_gone (GrdSessionVnc *session_vnc); - socket = g_socket_connection_get_socket (session_vnc->connection); -- -2.26.2 +2.44.0 diff --git a/sources b/sources new file mode 100644 index 0000000..8d54579 --- /dev/null +++ b/sources @@ -0,0 +1 @@ +SHA512 (gnome-remote-desktop-47.3.tar.xz) = 6a2da7fd3c09d47594eee53146fcc9c467844ce4d0282b4fb88f265016e3fd11f7ee5629cc70164427c024ad91b07021d5a5b9f771e983accc6019c17a0c5f7f