Open
[sync] PR-51: Fix CVE-2024-36472: Show notification when detecting captive portal #55
openeuler-ci-botAdd on Jun 2
[sync] PR-51: Fix CVE-2024-36472: Show notification when detecting captive portal #55
Open
openeuler-ci-botAdd on Jun 2
Total: 2 files changed+260-1
@@ -0,0 +1,255 @@
1+From 57de9ee874bff07b71dc323e54d5d721c4ded7fe Mon Sep 17 00:00:00 2001
2+From: Florian Müllner <fmuellner@gnome.org>
3+Date: Wed, 12 Jun 2024 13:13:41 +0200
4+Subject: [PATCH] network: Show notification when detecting captive portal
5+ 
6+When NetworkManager detects limited connectivity, we currently
7+pop up the portal helper window immediately. This can both be
8+disruptive when it happens unexpectedly, and unnoticeable
9+when it happens during screen lock.
10+ 
11+In any case, it seems better to not pop up a window without
12+explicit user action, so instead show a notification that
13+launches the portal window when activated.
14+ 
15+Backport of upstream commits:
16+ 57de9ee874b - network: Split out CaptivePortalHandler class
17+ 4ab1ccf3f21 - status/network: Show notification when detecting captive portal
18+ 
19+Adapted for gnome-shell 44.6 (openEuler-24.03-LTS-SP2).
20+ 
21+CVE: CVE-2024-36472
22+Upstream: https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3408
23+---
24+ js/ui/status/network.js | 185 ++++++++++++++++++++++++++--------------
25+ 1 file changed, 121 insertions(+), 64 deletions(-)
26+ 
27+diff --git a/js/ui/status/network.js b/js/ui/status/network.js
28+--- a/js/ui/status/network.js 2026-06-01 17:54:49.560042031 +0800
29++++ b/js/ui/status/network.js 2026-06-01 17:55:31.887793617 +0800
30+@@ -5,6 +5,7 @@
31+ const Main = imports.ui.main;
32+ const PopupMenu = imports.ui.popupMenu;
33+ const MessageTray = imports.ui.messageTray;
34++const Signals = imports.misc.signals;
35+ const ModemManager = imports.misc.modemManager;
36+ const Util = imports.misc.util;
37+
38+@@ -1932,11 +1933,115 @@
39+ });
40+
41+ var Indicator = GObject.registerClass(
42++ }
43++});
44++
45++class CaptivePortalHandler extends Signals.EventEmitter {
46++ constructor(checkUri) {
47++ super();
48++
49++ this._checkUri = checkUri;
50++ this._connectivityQueue = new Set();
51++ this._notifications = new Map();
52++ this._portalHelperProxy = null;
53++ }
54++
55++ addConnection(name, path) {
56++ if (this._connectivityQueue.has(path) || this._notifications.has(path))
57++ return;
58++
59++ const source = new MessageTray.SystemNotificationSource();
60++ source.connect('destroy', () => {});
61++ Main.messageTray.add(source);
62++
63++ const notification = new MessageTray.Notification(source,
64++ _('Sign Into Wi–Fi Network'),
65++ name);
66++ notification.connect('activated',
67++ () => this._onNotificationActivated(path));
68++ notification.connect('destroy',
69++ () => this._notifications.delete(path));
70++ this._notifications.set(path, notification);
71++ source.showNotification(notification);
72++ }
73++
74++
75++ removeConnection(path) {
76++ if (this._connectivityQueue.delete(path))
77++ this._portalHelperProxy?.CloseAsync(path);
78++ this._notifications.get(path)?.destroy(
79++ MessageTray.NotificationDestroyedReason.SOURCE_CLOSED);
80++ this._notifications.delete(path);
81++ }
82++
83++ _onNotificationActivated(path) {
84++ this._launchPortalHelper(path).catch(logError);
85++
86++ Main.overview.hide();
87++ Main.panel.closeCalendar();
88++ }
89++
90++ _portalHelperDone(parameters) {
91++ const [path, result] = parameters;
92++
93++ if (result === PortalHelperResult.CANCELLED) {
94++ // Keep the connection in the queue, so the user is not
95++ // spammed with more logins until we next flush the queue,
96++ // which will happen once they choose a better connection
97++ // or we get to full connectivity through other means
98++ } else if (result === PortalHelperResult.COMPLETED) {
99++ this.removeConnection(path);
100++ } else if (result === PortalHelperResult.RECHECK) {
101++ this.emit('recheck', path);
102++ } else {
103++ log(`Invalid result from portal helper: ${result}`);
104++ }
105++ }
106++
107++ async _launchPortalHelper(path) {
108++ const timestamp = global.get_current_time();
109++ if (!this._portalHelperProxy) {
110++ this._portalHelperProxy = new Gio.DBusProxy({
111++ g_connection: Gio.DBus.session,
112++ g_name: 'org.gnome.Shell.PortalHelper',
113++ g_object_path: '/org/gnome/Shell/PortalHelper',
114++ g_interface_name: PortalHelperInfo.name,
115++ g_interface_info: PortalHelperInfo,
116++ });
117++ this._portalHelperProxy.connectSignal('Done',
118++ (proxy, emitter, params) => {
119++ this._portalHelperDone(params);
120++ });
121++
122++ try {
123++ await this._portalHelperProxy.init_async(
124++ GLib.PRIORITY_DEFAULT, null);
125++ } catch (e) {
126++ console.error(`Error launching the portal helper: ${e.message}`);
127++ }
128++ }
129++
130++ this._portalHelperProxy?.AuthenticateAsync(path, this._checkUri, timestamp).catch(logError);
131++ this._connectivityQueue.add(path);
132++ }
133++
134++ clear() {
135++ for (const item of this._connectivityQueue)
136++ this._portalHelperProxy?.CloseAsync(item);
137++ this._connectivityQueue.clear();
138++
139++ for (const n of this._notifications.values())
140++ n.destroy(MessageTray.NotificationDestroyedReason.SOURCE_CLOSED);
141++ this._notifications.clear();
142++ }
143++}
144++
145+ class Indicator extends SystemIndicator {
146+ _init() {
147+ super._init();
148+
149+- this._connectivityQueue = new Set();
150++ this._portalHandler = null;
151++
152+
153+ this._mainConnection = null;
154+
155+@@ -1991,6 +2096,16 @@
156+ this, 'visible',
157+ GObject.BindingFlags.SYNC_CREATE);
158+
159++ const {connectivityCheckUri} = this._client;
160++ this._portalHandler = new CaptivePortalHandler(connectivityCheckUri);
161++ this._portalHandler.connect('recheck', async (o, path) => {
162++ try {
163++ const state = await this._client.check_connectivity_async(null);
164++ if (state >= NM.ConnectivityState.FULL)
165++ this._portalHandler.removeConnection(path);
166++ } catch (e) { }
167++ });
168++
169+ this._client.connectObject(
170+ 'notify::primary-connection', () => this._syncMainConnection(),
171+ 'notify::activating-connection', () => this._syncMainConnection(),
172+@@ -2055,42 +2170,10 @@
173+ this._notification?.destroy();
174+ }
175+
176+- _flushConnectivityQueue() {
177+- for (let item of this._connectivityQueue)
178+- this._portalHelperProxy?.CloseAsync(item);
179+- this._connectivityQueue.clear();
180+- }
181+-
182+- _closeConnectivityCheck(path) {
183+- if (this._connectivityQueue.delete(path))
184+- this._portalHelperProxy?.CloseAsync(path);
185+- }
186+-
187+- async _portalHelperDone(parameters) {
188+- let [path, result] = parameters;
189+-
190+- if (result == PortalHelperResult.CANCELLED) {
191+- // Keep the connection in the queue, so the user is not
192+- // spammed with more logins until we next flush the queue,
193+- // which will happen once they choose a better connection
194+- // or we get to full connectivity through other means
195+- } else if (result == PortalHelperResult.COMPLETED) {
196+- this._closeConnectivityCheck(path);
197+- } else if (result == PortalHelperResult.RECHECK) {
198+- try {
199+- const state = await this._client.check_connectivity_async(null);
200+- if (state >= NM.ConnectivityState.FULL)
201+- this._closeConnectivityCheck(path);
202+- } catch (e) { }
203+- } else {
204+- log(`Invalid result from portal helper: ${result}`);
205+- }
206+- }
207+-
208+- async _syncConnectivity() {
209++ _syncConnectivity() {
210+ if (this._mainConnection == null ||
211+ this._mainConnection.state != NM.ActiveConnectionState.ACTIVATED) {
212+- this._flushConnectivityQueue();
213++ this._portalHandler.clear();
214+ return;
215+ }
216+
217+@@ -2105,35 +2188,9 @@
218+ if (!isPortal || Main.sessionMode.isGreeter)
219+ return;
220+
221+- let path = this._mainConnection.get_path();
222+- if (this._connectivityQueue.has(path))
223+- return;
224+-
225+- let timestamp = global.get_current_time();
226+- if (!this._portalHelperProxy) {
227+- this._portalHelperProxy = new Gio.DBusProxy({
228+- g_connection: Gio.DBus.session,
229+- g_name: 'org.gnome.Shell.PortalHelper',
230+- g_object_path: '/org/gnome/Shell/PortalHelper',
231+- g_interface_name: PortalHelperInfo.name,
232+- g_interface_info: PortalHelperInfo,
233+- });
234+- this._portalHelperProxy.connectSignal('Done',
235+- (proxy, emitter, params) => {
236+- this._portalHelperDone(params).catch(logError);
237+- });
238+-
239+- try {
240+- await this._portalHelperProxy.init_async(
241+- GLib.PRIORITY_DEFAULT, null);
242+- } catch (e) {
243+- console.error(`Error launching the portal helper: ${e.message}`);
244+- }
245+- }
246+-
247+- this._portalHelperProxy?.AuthenticateAsync(path, this._client.connectivity_check_uri, timestamp).catch(logError);
248+-
249+- this._connectivityQueue.add(path);
250++ this._portalHandler.addConnection(
251++ this._mainConnection.get_id(),
252++ this._mainConnection.get_path());
253+ }
254+
255+ _updateIcon() {
@@ -17,7 +17,7 @@
17 17 
18Name: gnome-shell18Name: gnome-shell
19Version: 44.619Version: 44.6
20-Release: 120+Release: 2
21Summary: Core user interface functions for the GNOME 3 desktop21Summary: Core user interface functions for the GNOME 3 desktop
22Group: User Interface/Desktops22Group: User Interface/Desktops
23License: GPLv2+23License: GPLv2+
@@ -25,6 +25,7 @@ URL: https://wiki.gnome.org/Projects/GnomeShell
25Source0: https://download.gnome.org/sources/gnome-shell/44/%{name}-%{version}.tar.xz25Source0: https://download.gnome.org/sources/gnome-shell/44/%{name}-%{version}.tar.xz
26Patch10001: gnome-shell-favourite-apps-firefox.patch26Patch10001: gnome-shell-favourite-apps-firefox.patch
27Patch40001: 0001-gdm-Work-around-failing-fingerprint-auth.patch27Patch40001: 0001-gdm-Work-around-failing-fingerprint-auth.patch
28+Patch40002: backport-CVE-2024-36472.patch
28 29 
29BuildRequires: bash-completion gcc meson mesa-libGL-devel mesa-libEGL-devel 30BuildRequires: bash-completion gcc meson mesa-libGL-devel mesa-libEGL-devel
30BuildRequires: gtk-doc desktop-file-utils python3 librsvg2-devel chrpath cmake31BuildRequires: gtk-doc desktop-file-utils python3 librsvg2-devel chrpath cmake
@@ -186,6 +187,9 @@ glib-compile-schemas --allow-any-name %{_datadir}/glib-2.0/schemas &> /dev/null
186%{_mandir}/man1/gnome-shell.1*187%{_mandir}/man1/gnome-shell.1*
187 188 
188%changelog189%changelog
190+* Mon Jun 01 2026 herengui <herengui@kylinsec.com.cn> - 44.6-2
191+- Fix CVE-2024-36472: Show notification with user activation before launching portal helper
192+ 
189* Mon Nov 27 2023 lwg <liweiganga@uniontech.com> - 44.6-1193* Mon Nov 27 2023 lwg <liweiganga@uniontech.com> - 44.6-1
190- update to version 44.6194- update to version 44.6
191 195