Skip to content

Commit

Permalink
bolt: Enable bolt support in NILRT
Browse files Browse the repository at this point in the history
This commit contains following changes required for bolt to work

 - Patch from upstream to allow running bolt without polkit
 - Patch to allow all commands to be run without authorization (making
   way for dbus to handle authorization).
 - dbus rules to allow only admin to run privileged commands of boltctl
 - udev rule to remove dependency on systemd and start boltd
   directly. udev rule useful in cases where thunderbolt device is
   connected after host boots.
 - initscript to start boltd only when thunderbolt devices are present
   on the host. initscript useful in cases where thunderbolt device is
   already connected when host boots and udev isn't able to start boltd
   because it runs before dbus (a dependency for boltd).
 - Wrapper around boltctl so it runs with LANG set to UTF-8 in order to
   display non-ASCII characters correctly.

Signed-off-by: Chaitanya Vadrevu <chaitanya.vadrevu@ni.com>

Overwrite udev rules file instead of patching

Overwrite dbus rule file instead of patching
  • Loading branch information
chaitu236 committed Aug 14, 2023
1 parent ee67652 commit ce67c6e
Show file tree
Hide file tree
Showing 7 changed files with 356 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
From 86d2596b8da2bef9dd33579b104916aaafbff3ab Mon Sep 17 00:00:00 2001
From: Christian Kellner <christian@kellner.me>
Date: Mon, 28 Sep 2020 19:56:16 +0200
Subject: [PATCH] daemon: support running without PolicyKit

Make the dependency on PolicyKit optional. In that case, don't
allow all methods and property access and fall back on the
standard D-Bus policies. NB: These are designed to work with
PolicyKit so most likely are not suitable at all. This is
designed for a special use case not intended for general use.

Since PolicyKit is the normal mode of operation, this feature
requires explicit opt-in, via the new `require-polkit` configure
option.
---
boltd/bolt-bouncer.c | 27 ++++++++++++++++++++++++++-
config.h.in | 1 +
meson.build | 4 +++-
meson_options.txt | 1 +
4 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/boltd/bolt-bouncer.c b/boltd/bolt-bouncer.c
index 1a65c46..e3218de 100644
--- a/boltd/bolt-bouncer.c
+++ b/boltd/bolt-bouncer.c
@@ -28,7 +28,10 @@
#include "bolt-exported.h"

#include <gio/gio.h>
+
+#if HAVE_POLKIT
#include <polkit/polkit.h>
+#endif

static void bouncer_initable_iface_init (GInitableIface *iface);

@@ -37,7 +40,7 @@ static gboolean bouncer_initialize (GInitable *initable,
GCancellable *cancellable,
GError **error);

-#ifndef HAVE_POLKIT_AUTOPTR
+#if HAVE_POLKIT && !defined HAVE_POLKIT_AUTOPTR
G_DEFINE_AUTOPTR_CLEANUP_FUNC (PolkitAuthorizationResult, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (PolkitDetails, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (PolkitSubject, g_object_unref)
@@ -48,7 +51,9 @@ struct _BoltBouncer
GObject object;

/* */
+#if HAVE_POLKIT
PolkitAuthority *authority;
+#endif
};

G_DEFINE_TYPE_WITH_CODE (BoltBouncer, bolt_bouncer, G_TYPE_OBJECT,
@@ -61,7 +66,11 @@ bolt_bouncer_finalize (GObject *object)
{
BoltBouncer *bouncer = BOLT_BOUNCER (object);

+ g_assert (BOLT_IS_BOUNCER (bouncer));
+
+#if HAVE_POLKIT
g_clear_object (&bouncer->authority);
+#endif

G_OBJECT_CLASS (bolt_bouncer_parent_class)->finalize (object);
}
@@ -86,11 +95,13 @@ bouncer_initable_iface_init (GInitableIface *iface)
iface->init = bouncer_initialize;
}

+#if HAVE_POLKIT
static gboolean
bouncer_initialize (GInitable *initable,
GCancellable *cancellable,
GError **error)
{
+
BoltBouncer *bnc = BOLT_BOUNCER (initable);

bolt_info (LOG_TOPIC ("bouncer"), "initializing polkit");
@@ -98,9 +109,20 @@ bouncer_initialize (GInitable *initable,

return bnc->authority != NULL;
}
+#else /* HAVE_POLKIT */
+static gboolean
+bouncer_initialize (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error)
+{
+ bolt_info (LOG_TOPIC ("bouncer"), "Checking DISABLED (polkit missing)");
+ return TRUE;
+}
+#endif /* HAVE_POLKIT */

/* internal methods */

+#if HAVE_POLKIT
static gboolean
bolt_bouncer_check_action (BoltBouncer *bnc,
GDBusMethodInvocation *inv,
@@ -252,6 +274,7 @@ handle_authorize_property (BoltExported *exported,

return authorized;
}
+#endif

/* public methods */
BoltBouncer *
@@ -271,6 +294,7 @@ bolt_bouncer_add_client (BoltBouncer *bnc,
g_return_if_fail (BOLT_IS_BOUNCER (bnc));
g_return_if_fail (BOLT_IS_EXPORTED (client));

+#if HAVE_POLKIT
g_signal_connect_object (client, "authorize-method",
G_CALLBACK (handle_authorize_method),
bnc, 0);
@@ -278,4 +302,5 @@ bolt_bouncer_add_client (BoltBouncer *bnc,
g_signal_connect_object (client, "authorize-property",
G_CALLBACK (handle_authorize_property),
bnc, 0);
+#endif
}
diff --git a/config.h.in b/config.h.in
index eba23a3..0b94246 100644
--- a/config.h.in
+++ b/config.h.in
@@ -38,6 +38,7 @@
#mesondefine HAVE_FN_EXPLICIT_BZERO
#mesondefine HAVE_FN_GETRANDOM
#mesondefine HAVE_FN_COPY_FILE_RANGE
+#mesondefine HAVE_POLKIT
#mesondefine HAVE_POLKIT_AUTOPTR

/* constants */
diff --git a/meson.build b/meson.build
index 32e48d2..2073079 100644
--- a/meson.build
+++ b/meson.build
@@ -66,6 +66,7 @@ endforeach

build_man = get_option('man')
req_man = build_man == 'true'
+req_polkit = get_option('polkit-required')

# dependencies

@@ -81,7 +82,7 @@ gio = dependency('gio-2.0')
libudev = dependency('libudev')
unix = dependency('gio-unix-2.0')
udev = dependency('udev')
-polkit = dependency('polkit-gobject-1')
+polkit = dependency('polkit-gobject-1', required: req_polkit)
mockdev = dependency('umockdev-1.0', required: false)

git = find_program('git', required: false)
@@ -152,6 +153,7 @@ foreach fn : [
conf.set10('HAVE_FN_' + fn[0].to_upper(), have)
endforeach

+conf.set10('HAVE_POLKIT', polkit.found())
if polkit.version().version_compare('>= 0.114')
conf.set('HAVE_POLKIT_AUTOPTR', '1')
endif
diff --git a/meson_options.txt b/meson_options.txt
index 467f73e..880ca3e 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -3,6 +3,7 @@ option('db-path', type: 'string', description: 'DEPRECATED')
option('db-name', type: 'string', value: 'boltd', description: 'Name for the device database')
option('install-tests', type: 'boolean', value: 'false', description: 'Install the tests')
option('man', type: 'combo', choices: ['auto', 'true', 'false'], value: 'auto', description: 'Build man pages')
+option('polkit-required', type: 'boolean', value: 'true', description: 'Require PolicyKit integration')
option('privileged-group', type: 'string', value: 'wheel', description: 'Name of privileged group')
option('profiling', type: 'boolean', value: 'false', description: 'Build with profiling support')
option('systemd', type: 'boolean', value: 'true', description: 'DEPRECATED')
--
2.34.1

Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
From 26f0a98d57ddcc91a90730d98c0b5ccc298f9328 Mon Sep 17 00:00:00 2001
From: Chaitanya Vadrevu <chaitanya.vadrevu@ni.com>
Date: Fri, 11 Aug 2023 15:24:56 -0500
Subject: [PATCH] exported: authorize all methods by default

Without polkit, no method is authorized by default.
We will be using dbus rules to control users' access to individual
methods. So authorize all methods by default in bolt.

Upstream-Status: Inappropriate [NI-specific changes]

Signed-off-by: Chaitanya Vadrevu <chaitanya.vadrevu@ni.com>
---
boltd/bolt-exported.c | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/boltd/bolt-exported.c b/boltd/bolt-exported.c
index 3c0ffb0..8a77b27 100644
--- a/boltd/bolt-exported.c
+++ b/boltd/bolt-exported.c
@@ -593,14 +593,7 @@ handle_authorize_method_default (BoltExported *exported,
GDBusMethodInvocation *inv,
GError **error)
{
- const char *method_name;
-
- method_name = g_dbus_method_invocation_get_method_name (inv);
- g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_ACCESS_DENIED,
- "bolt operation '%s' denied by default policy",
- method_name);
-
- return FALSE;
+ return TRUE;
}

static gboolean
16 changes: 16 additions & 0 deletions recipes-bsp/bolt/bolt/90-bolt.rules
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# bolt udev rules
#
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Copyright © 2017 Red Hat, Inc
#
# Authors:
# Christian J. Kellner <ckellner@redhat.com>
#

ACTION=="remove", GOTO="bolt_end"

# start bolt service if we have a thunderbolt device connected
ACTION=="add", SUBSYSTEM=="thunderbolt", ENV{DEVTYPE}=="thunderbolt_domain", RUN{program}+="/usr/bin/boltctl"

LABEL="bolt_end"
17 changes: 17 additions & 0 deletions recipes-bsp/bolt/bolt/bolt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/sh

### BEGIN INIT INFO
# Provides: bolt
# Required-Start: dbus
# Required-Stop:
# Default-Start: 2 3 5
# Default-Stop:
# Short-Description: Start boltd
# Description: Start boltd when thunderbolt devices are present at boot time.
# For cases when thunderbolt is connected after boot, udev will
# take care of starting it.
### END INIT INFO

# boltctl causes /usr/libexec/boltd to run as a daemon so just call it instead
# of explicitly daemonizing boltd.
[ -d "/sys/bus/thunderbolt" ] && boltctl
5 changes: 5 additions & 0 deletions recipes-bsp/bolt/bolt/boltctl
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/sh

# The purpose of this wrapper is to set LANG to UTF-8 so that non ASCII
# characters in the output of boltctl can be displayed correctly
LANG=en_US.UTF-8 /usr/libexec/boltctl "$@"
67 changes: 67 additions & 0 deletions recipes-bsp/bolt/bolt/org.freedesktop.bolt.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?> <!-- -*- XML -*- -->

<!DOCTYPE busconfig PUBLIC
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">

<busconfig>

<policy user="root">
<allow own="org.freedesktop.bolt"/>
</policy>

<policy context="default">

<allow send_destination="org.freedesktop.bolt"
send_interface="org.freedesktop.DBus.Introspectable"/>

<allow send_destination="org.freedesktop.bolt"
send_interface="org.freedesktop.DBus.Peer"/>

<allow send_destination="org.freedesktop.bolt"
send_interface="org.freedesktop.DBus.Properties"/>


<allow send_destination="org.freedesktop.bolt"
send_interface="org.freedesktop.bolt1.Manager" />

<allow send_destination="org.freedesktop.bolt"
send_interface="org.freedesktop.bolt1.Domain" />

<allow send_destination="org.freedesktop.bolt"
send_interface="org.freedesktop.bolt1.Device" />

<allow send_destination="org.freedesktop.bolt"
send_interface="org.freedesktop.bolt1.Power" />

<deny send_destination="org.freedesktop.bolt"
send_interface="org.freedesktop.bolt1.Manager" send_member="EnrollDevice"/>

<deny send_destination="org.freedesktop.bolt"
send_interface="org.freedesktop.bolt1.Device" send_member="Authorize"/>

<deny send_destination="org.freedesktop.bolt"
send_interface="org.freedesktop.bolt1.Manager" send_member="ForgetDevice"/>

<deny send_destination="org.freedesktop.bolt"
send_interface="org.freedesktop.bolt1.Power" send_member="ForcePower"/>

</policy>

<policy user="root">

<allow send_destination="org.freedesktop.bolt"
send_interface="org.freedesktop.bolt1.Manager" send_member="EnrollDevice"/>

<allow send_destination="org.freedesktop.bolt"
send_interface="org.freedesktop.bolt1.Device" send_member="Authorize"/>

<allow send_destination="org.freedesktop.bolt"
send_interface="org.freedesktop.bolt1.Manager" send_member="ForgetDevice"/>

<allow send_destination="org.freedesktop.bolt"
send_interface="org.freedesktop.bolt1.Power" send_member="ForcePower"/>

</policy>

</busconfig>
35 changes: 35 additions & 0 deletions recipes-bsp/bolt/bolt_%.bbappend
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"

DEPENDS += "update-rc.d-native"
DEPENDS:remove = "polkit"

SRC_URI += "\
file://bolt \
file://boltctl \
file://90-bolt.rules \
file://org.freedesktop.bolt.conf \
file://0001-daemon-support-running-without-PolicyKit.patch \
file://0002-exported-authorize-all-methods-by-default.patch \
"

FILES:${PN} += "${sysconfdir}/init.d/bolt"

EXTRA_OEMESON = "-Dpolkit-required=false"

do_install:append() {
install -d ${D}${sysconfdir}/init.d
install -m 0755 ${WORKDIR}/bolt ${D}${sysconfdir}/init.d/bolt

# Move boltctl to a directory that's not in PATH and install a wrapper
# in its place
mv ${D}${bindir}/boltctl ${D}${libexecdir}/
install -m 0755 ${WORKDIR}/boltctl ${D}${bindir}/

# Overwrite udev rules file so it works on systems without systemd
install -m 0644 ${WORKDIR}/90-bolt.rules ${D}${base_libdir}/udev/rules.d/

# Overwrite dbus config file to allow only root to run privileged commands
install -m 0644 ${WORKDIR}/org.freedesktop.bolt.conf ${D}${datadir}/dbus-1/system.d/

update-rc.d -r ${D} bolt start 3 2 3 5 .
}

0 comments on commit ce67c6e

Please sign in to comment.