gio/auto/debug_controller_dbus.rs
1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// DO NOT EDIT
4
5use crate::{ffi, Cancellable, DBusConnection, DBusMethodInvocation, DebugController, Initable};
6use glib::{
7 object::ObjectType as _,
8 prelude::*,
9 signal::{connect_raw, SignalHandlerId},
10 translate::*,
11};
12use std::boxed::Box as Box_;
13
14glib::wrapper! {
15 /// `GDebugControllerDBus` is an implementation of [`DebugController`][crate::DebugController]
16 /// which exposes debug settings as a D-Bus object.
17 ///
18 /// It is a [`Initable`][crate::Initable] object, and will register an object at
19 /// `/org/gtk/Debugging` on the bus given as
20 /// [`connection`][struct@crate::DebugControllerDBus#connection] once it’s initialized. The
21 /// object will be unregistered when the last reference to the
22 /// `GDebugControllerDBus` is dropped.
23 ///
24 /// This D-Bus object can be used by remote processes to enable or disable debug
25 /// output in this process. Remote processes calling
26 /// `org.gtk.Debugging.SetDebugEnabled()` will affect the value of
27 /// [`debug-enabled`][struct@crate::DebugController#debug-enabled] and, by default,
28 /// `log_get_debug_enabled()`.
29 ///
30 /// By default, no processes are allowed to call `SetDebugEnabled()` unless a
31 /// [`authorize`][struct@crate::DebugControllerDBus#authorize] signal handler is installed. This
32 /// is because the process may be privileged, or might expose sensitive
33 /// information in its debug output. You may want to restrict the ability to
34 /// enable debug output to privileged users or processes.
35 ///
36 /// One option is to install a D-Bus security policy which restricts access to
37 /// `SetDebugEnabled()`, installing something like the following in
38 /// `$datadir/dbus-1/system.d/`:
39 ///
40 /// ```xml
41 /// <?xml version="1.0"?> <!--*-nxml-*-->
42 /// <!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
43 /// "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
44 /// <busconfig>
45 /// <policy user="root">
46 /// <allow send_destination="com.example.MyService" send_interface="org.gtk.Debugging"/>
47 /// </policy>
48 /// <policy context="default">
49 /// <deny send_destination="com.example.MyService" send_interface="org.gtk.Debugging"/>
50 /// </policy>
51 /// </busconfig>
52 /// ```
53 ///
54 /// This will prevent the `SetDebugEnabled()` method from being called by all
55 /// except root. It will not prevent the `DebugEnabled` property from being read,
56 /// as it’s accessed through the `org.freedesktop.DBus.Properties` interface.
57 ///
58 /// Another option is to use polkit to allow or deny requests on a case-by-case
59 /// basis, allowing for the possibility of dynamic authorisation. To do this,
60 /// connect to the [`authorize`][struct@crate::DebugControllerDBus#authorize] signal and query
61 /// polkit in it:
62 ///
63 /// **⚠️ The following code is in c ⚠️**
64 ///
65 /// ```c
66 /// g_autoptr(GError) child_error = NULL;
67 /// g_autoptr(GDBusConnection) connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL);
68 /// gulong debug_controller_authorize_id = 0;
69 ///
70 /// // Set up the debug controller.
71 /// debug_controller = G_DEBUG_CONTROLLER (g_debug_controller_dbus_new (priv->connection, NULL, &child_error));
72 /// if (debug_controller == NULL)
73 /// {
74 /// g_error ("Could not register debug controller on bus: %s"),
75 /// child_error->message);
76 /// }
77 ///
78 /// debug_controller_authorize_id = g_signal_connect (debug_controller,
79 /// "authorize",
80 /// G_CALLBACK (debug_controller_authorize_cb),
81 /// self);
82 ///
83 /// static gboolean
84 /// debug_controller_authorize_cb (GDebugControllerDBus *debug_controller,
85 /// GDBusMethodInvocation *invocation,
86 /// gpointer user_data)
87 /// {
88 /// g_autoptr(PolkitAuthority) authority = NULL;
89 /// g_autoptr(PolkitSubject) subject = NULL;
90 /// g_autoptr(PolkitAuthorizationResult) auth_result = NULL;
91 /// g_autoptr(GError) local_error = NULL;
92 /// GDBusMessage *message;
93 /// GDBusMessageFlags message_flags;
94 /// PolkitCheckAuthorizationFlags flags = POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE;
95 ///
96 /// message = g_dbus_method_invocation_get_message (invocation);
97 /// message_flags = g_dbus_message_get_flags (message);
98 ///
99 /// authority = polkit_authority_get_sync (NULL, &local_error);
100 /// if (authority == NULL)
101 /// {
102 /// g_warning ("Failed to get polkit authority: %s", local_error->message);
103 /// return FALSE;
104 /// }
105 ///
106 /// if (message_flags & G_DBUS_MESSAGE_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION)
107 /// flags |= POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION;
108 ///
109 /// subject = polkit_system_bus_name_new (g_dbus_method_invocation_get_sender (invocation));
110 ///
111 /// auth_result = polkit_authority_check_authorization_sync (authority,
112 /// subject,
113 /// "com.example.MyService.set-debug-enabled",
114 /// NULL,
115 /// flags,
116 /// NULL,
117 /// &local_error);
118 /// if (auth_result == NULL)
119 /// {
120 /// g_warning ("Failed to get check polkit authorization: %s", local_error->message);
121 /// return FALSE;
122 /// }
123 ///
124 /// return polkit_authorization_result_get_is_authorized (auth_result);
125 /// }
126 /// ```
127 ///
128 /// ## Properties
129 ///
130 ///
131 /// #### `connection`
132 /// The D-Bus connection to expose the debugging interface on.
133 ///
134 /// Typically this will be the same connection (to the system or session bus)
135 /// which the rest of the application or service’s D-Bus objects are registered
136 /// on.
137 ///
138 /// Readable | Writeable | Construct Only
139 /// <details><summary><h4>DebugController</h4></summary>
140 ///
141 ///
142 /// #### `debug-enabled`
143 /// [`true`] if debug output should be exposed (for example by forwarding it to
144 /// the journal), [`false`] otherwise.
145 ///
146 /// Readable | Writeable
147 /// </details>
148 ///
149 /// ## Signals
150 ///
151 ///
152 /// #### `authorize`
153 /// Emitted when a D-Bus peer is trying to change the debug settings and used
154 /// to determine if that is authorized.
155 ///
156 /// This signal is emitted in a dedicated worker thread, so handlers are
157 /// allowed to perform blocking I/O. This means that, for example, it is
158 /// appropriate to call `polkit_authority_check_authorization_sync()` to check
159 /// authorization using polkit.
160 ///
161 /// If [`false`] is returned then no further handlers are run and the request to
162 /// change the debug settings is rejected.
163 ///
164 /// Otherwise, if [`true`] is returned, signal emission continues. If no handlers
165 /// return [`false`], then the debug settings are allowed to be changed.
166 ///
167 /// Signal handlers must not modify @invocation, or cause it to return a value.
168 ///
169 /// The default class handler just returns [`true`].
170 ///
171 ///
172 ///
173 /// # Implements
174 ///
175 /// [`DebugControllerDBusExt`][trait@crate::prelude::DebugControllerDBusExt], [`trait@glib::ObjectExt`], [`DebugControllerExt`][trait@crate::prelude::DebugControllerExt], [`InitableExt`][trait@crate::prelude::InitableExt], [`DebugControllerDBusExtManual`][trait@crate::prelude::DebugControllerDBusExtManual]
176 #[doc(alias = "GDebugControllerDBus")]
177 pub struct DebugControllerDBus(Object<ffi::GDebugControllerDBus, ffi::GDebugControllerDBusClass>) @implements DebugController, Initable;
178
179 match fn {
180 type_ => || ffi::g_debug_controller_dbus_get_type(),
181 }
182}
183
184impl DebugControllerDBus {
185 pub const NONE: Option<&'static DebugControllerDBus> = None;
186
187 /// Create a new #GDebugControllerDBus and synchronously initialize it.
188 ///
189 /// Initializing the object will export the debug object on @connection. The
190 /// object will remain registered until the last reference to the
191 /// #GDebugControllerDBus is dropped.
192 ///
193 /// Initialization may fail if registering the object on @connection fails.
194 /// ## `connection`
195 /// a #GDBusConnection to register the debug object on
196 /// ## `cancellable`
197 /// a #GCancellable, or [`None`]
198 ///
199 /// # Returns
200 ///
201 /// a new #GDebugControllerDBus, or [`None`]
202 /// on failure
203 #[doc(alias = "g_debug_controller_dbus_new")]
204 pub fn new(
205 connection: &DBusConnection,
206 cancellable: Option<&impl IsA<Cancellable>>,
207 ) -> Result<Option<DebugControllerDBus>, glib::Error> {
208 unsafe {
209 let mut error = std::ptr::null_mut();
210 let ret = ffi::g_debug_controller_dbus_new(
211 connection.to_glib_none().0,
212 cancellable.map(|p| p.as_ref()).to_glib_none().0,
213 &mut error,
214 );
215 if error.is_null() {
216 Ok(from_glib_full(ret))
217 } else {
218 Err(from_glib_full(error))
219 }
220 }
221 }
222}
223
224mod sealed {
225 pub trait Sealed {}
226 impl<T: super::IsA<super::DebugControllerDBus>> Sealed for T {}
227}
228
229/// Trait containing all [`struct@DebugControllerDBus`] methods.
230///
231/// # Implementors
232///
233/// [`DebugControllerDBus`][struct@crate::DebugControllerDBus]
234pub trait DebugControllerDBusExt: IsA<DebugControllerDBus> + sealed::Sealed + 'static {
235 /// Stop the debug controller, unregistering its object from the bus.
236 ///
237 /// Any pending method calls to the object will complete successfully, but new
238 /// ones will return an error. This method will block until all pending
239 /// #GDebugControllerDBus::authorize signals have been handled. This is expected
240 /// to not take long, as it will just be waiting for threads to join. If any
241 /// #GDebugControllerDBus::authorize signal handlers are still executing in other
242 /// threads, this will block until after they have returned.
243 ///
244 /// This method will be called automatically when the final reference to the
245 /// #GDebugControllerDBus is dropped. You may want to call it explicitly to know
246 /// when the controller has been fully removed from the bus, or to break
247 /// reference count cycles.
248 ///
249 /// Calling this method from within a #GDebugControllerDBus::authorize signal
250 /// handler will cause a deadlock and must not be done.
251 #[doc(alias = "g_debug_controller_dbus_stop")]
252 fn stop(&self) {
253 unsafe {
254 ffi::g_debug_controller_dbus_stop(self.as_ref().to_glib_none().0);
255 }
256 }
257
258 /// Emitted when a D-Bus peer is trying to change the debug settings and used
259 /// to determine if that is authorized.
260 ///
261 /// This signal is emitted in a dedicated worker thread, so handlers are
262 /// allowed to perform blocking I/O. This means that, for example, it is
263 /// appropriate to call `polkit_authority_check_authorization_sync()` to check
264 /// authorization using polkit.
265 ///
266 /// If [`false`] is returned then no further handlers are run and the request to
267 /// change the debug settings is rejected.
268 ///
269 /// Otherwise, if [`true`] is returned, signal emission continues. If no handlers
270 /// return [`false`], then the debug settings are allowed to be changed.
271 ///
272 /// Signal handlers must not modify @invocation, or cause it to return a value.
273 ///
274 /// The default class handler just returns [`true`].
275 /// ## `invocation`
276 /// A #GDBusMethodInvocation.
277 ///
278 /// # Returns
279 ///
280 /// [`true`] if the call is authorized, [`false`] otherwise.
281 #[cfg(feature = "v2_72")]
282 #[cfg_attr(docsrs, doc(cfg(feature = "v2_72")))]
283 #[doc(alias = "authorize")]
284 fn connect_authorize<F: Fn(&Self, &DBusMethodInvocation) -> bool + 'static>(
285 &self,
286 f: F,
287 ) -> SignalHandlerId {
288 unsafe extern "C" fn authorize_trampoline<
289 P: IsA<DebugControllerDBus>,
290 F: Fn(&P, &DBusMethodInvocation) -> bool + 'static,
291 >(
292 this: *mut ffi::GDebugControllerDBus,
293 invocation: *mut ffi::GDBusMethodInvocation,
294 f: glib::ffi::gpointer,
295 ) -> glib::ffi::gboolean {
296 let f: &F = &*(f as *const F);
297 f(
298 DebugControllerDBus::from_glib_borrow(this).unsafe_cast_ref(),
299 &from_glib_borrow(invocation),
300 )
301 .into_glib()
302 }
303 unsafe {
304 let f: Box_<F> = Box_::new(f);
305 connect_raw(
306 self.as_ptr() as *mut _,
307 b"authorize\0".as_ptr() as *const _,
308 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
309 authorize_trampoline::<Self, F> as *const (),
310 )),
311 Box_::into_raw(f),
312 )
313 }
314 }
315}
316
317impl<O: IsA<DebugControllerDBus>> DebugControllerDBusExt for O {}