[gnome-shell] introspect: Split out DBusSenderChecker
- From: Marge Bot <marge-bot src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell] introspect: Split out DBusSenderChecker
- Date: Fri, 3 Sep 2021 21:44:30 +0000 (UTC)
commit 2a3e297218c85dd1d198bdecdd0768ae85e97f09
Author: Florian Müllner <fmuellner gnome org>
Date: Wed Jun 16 19:09:42 2021 +0200
introspect: Split out DBusSenderChecker
Restricting callers to a list of allowed senders is useful for
other D-Bus services as well, so split out the existing code
into a reusable class.
https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3943
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1970>
js/misc/introspect.js | 30 ++++-----------------------
js/misc/util.js | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 60 insertions(+), 27 deletions(-)
---
diff --git a/js/misc/introspect.js b/js/misc/introspect.js
index 8e469fbea3..22bd8319c4 100644
--- a/js/misc/introspect.js
+++ b/js/misc/introspect.js
@@ -9,6 +9,7 @@ const APP_ALLOWLIST = [
const INTROSPECT_DBUS_API_VERSION = 3;
const { loadInterfaceXML } = imports.misc.fileUtils;
+const { DBusSenderChecker } = imports.misc.util;
const IntrospectDBusIface = loadInterfaceXML('org.gnome.Shell.Introspect');
@@ -43,14 +44,7 @@ var IntrospectService = class {
this._syncRunningApplications();
- this._allowlistMap = new Map();
- APP_ALLOWLIST.forEach(appName => {
- Gio.DBus.watch_name(Gio.BusType.SESSION,
- appName,
- Gio.BusNameWatcherFlags.NONE,
- (conn, name, owner) => this._allowlistMap.set(name, owner),
- (conn, name) => this._allowlistMap.delete(name));
- });
+ this._senderChecker = new DBusSenderChecker(APP_ALLOWLIST);
this._settings = St.Settings.get();
this._settings.connect('notify::enable-animations',
@@ -67,10 +61,6 @@ var IntrospectService = class {
return app.get_windows().some(w => w.transient_for == null);
}
- _isSenderAllowed(sender) {
- return [...this._allowlistMap.values()].includes(sender);
- }
-
_getSandboxedAppId(app) {
let ids = app.get_windows().map(w => w.get_sandboxed_app_id());
return ids.find(id => id != null);
@@ -127,21 +117,9 @@ var IntrospectService = class {
type == Meta.WindowType.UTILITY;
}
- _checkInvocation(invocation) {
- if (global.context.unsafe_mode)
- return;
-
- if (this._isSenderAllowed(invocation.get_sender()))
- return;
-
- throw new GLib.Error(Gio.DBusError,
- Gio.DBusError.ACCESS_DENIED,
- 'App introspection not allowed');
- }
-
GetRunningApplicationsAsync(params, invocation) {
try {
- this._checkInvocation(invocation);
+ this._senderChecker.checkInvocation(invocation);
} catch (e) {
invocation.return_gerror(e);
return;
@@ -156,7 +134,7 @@ var IntrospectService = class {
let windowsList = {};
try {
- this._checkInvocation(invocation);
+ this._senderChecker.checkInvocation(invocation);
} catch (e) {
invocation.return_gerror(e);
return;
diff --git a/js/misc/util.js b/js/misc/util.js
index 8139d3f47c..bd57184728 100644
--- a/js/misc/util.js
+++ b/js/misc/util.js
@@ -1,7 +1,8 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported findUrls, spawn, spawnCommandLine, spawnApp, trySpawnCommandLine,
formatTime, formatTimeSpan, createTimeLabel, insertSorted,
- ensureActorVisibleInScrollView, wiggle, lerp, GNOMEversionCompare */
+ ensureActorVisibleInScrollView, wiggle, lerp, GNOMEversionCompare,
+ DBusSenderChecker */
const { Clutter, Gio, GLib, Shell, St, GnomeDesktop } = imports.gi;
const Gettext = imports.gettext;
@@ -477,3 +478,57 @@ function GNOMEversionCompare(version1, version2) {
return 0;
}
+
+var DBusSenderChecker = class {
+ /**
+ * @param {string[]} allowList - list of allowed well-known names
+ */
+ constructor(allowList) {
+ this._allowlistMap = new Map();
+
+ this._watchList = allowList.map(name => {
+ return Gio.DBus.watch_name(Gio.BusType.SESSION,
+ name,
+ Gio.BusNameWatcherFlags.NONE,
+ (conn_, name_, owner) => this._allowlistMap.set(name, owner),
+ () => this._allowlistMap.delete(name));
+ });
+ }
+
+ /**
+ * @param {string} sender - the bus name that invoked the checked method
+ * @returns {bool}
+ */
+ _isSenderAllowed(sender) {
+ return [...this._allowlistMap.values()].includes(sender);
+ }
+
+ /**
+ * Check whether the bus name that invoked @invocation maps
+ * to an entry in the allow list.
+ *
+ * @throws
+ * @param {Gio.DBusMethodInvocation} invocation - the invocation
+ * @returns {void}
+ */
+ checkInvocation(invocation) {
+ if (global.context.unsafe_mode)
+ return;
+
+ if (this._isSenderAllowed(invocation.get_sender()))
+ return;
+
+ throw new GLib.Error(Gio.DBusError,
+ Gio.DBusError.ACCESS_DENIED,
+ '%s is not allowed'.format(invocation.get_method_name()));
+ }
+
+ /**
+ * @returns {void}
+ */
+ destroy() {
+ for (const id in this._watchList)
+ Gio.DBus.unwatch_name(id);
+ this._watchList = [];
+ }
+};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]