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
224/// Trait containing all [`struct@DebugControllerDBus`] methods.
225///
226/// # Implementors
227///
228/// [`DebugControllerDBus`][struct@crate::DebugControllerDBus]
229pub trait DebugControllerDBusExt: IsA<DebugControllerDBus> + 'static {
230    /// Stop the debug controller, unregistering its object from the bus.
231    ///
232    /// Any pending method calls to the object will complete successfully, but new
233    /// ones will return an error. This method will block until all pending
234    /// #GDebugControllerDBus::authorize signals have been handled. This is expected
235    /// to not take long, as it will just be waiting for threads to join. If any
236    /// #GDebugControllerDBus::authorize signal handlers are still executing in other
237    /// threads, this will block until after they have returned.
238    ///
239    /// This method will be called automatically when the final reference to the
240    /// #GDebugControllerDBus is dropped. You may want to call it explicitly to know
241    /// when the controller has been fully removed from the bus, or to break
242    /// reference count cycles.
243    ///
244    /// Calling this method from within a #GDebugControllerDBus::authorize signal
245    /// handler will cause a deadlock and must not be done.
246    #[doc(alias = "g_debug_controller_dbus_stop")]
247    fn stop(&self) {
248        unsafe {
249            ffi::g_debug_controller_dbus_stop(self.as_ref().to_glib_none().0);
250        }
251    }
252
253    /// Emitted when a D-Bus peer is trying to change the debug settings and used
254    /// to determine if that is authorized.
255    ///
256    /// This signal is emitted in a dedicated worker thread, so handlers are
257    /// allowed to perform blocking I/O. This means that, for example, it is
258    /// appropriate to call `polkit_authority_check_authorization_sync()` to check
259    /// authorization using polkit.
260    ///
261    /// If [`false`] is returned then no further handlers are run and the request to
262    /// change the debug settings is rejected.
263    ///
264    /// Otherwise, if [`true`] is returned, signal emission continues. If no handlers
265    /// return [`false`], then the debug settings are allowed to be changed.
266    ///
267    /// Signal handlers must not modify @invocation, or cause it to return a value.
268    ///
269    /// The default class handler just returns [`true`].
270    /// ## `invocation`
271    /// A #GDBusMethodInvocation.
272    ///
273    /// # Returns
274    ///
275    /// [`true`] if the call is authorized, [`false`] otherwise.
276    #[cfg(feature = "v2_72")]
277    #[cfg_attr(docsrs, doc(cfg(feature = "v2_72")))]
278    #[doc(alias = "authorize")]
279    fn connect_authorize<F: Fn(&Self, &DBusMethodInvocation) -> bool + 'static>(
280        &self,
281        f: F,
282    ) -> SignalHandlerId {
283        unsafe extern "C" fn authorize_trampoline<
284            P: IsA<DebugControllerDBus>,
285            F: Fn(&P, &DBusMethodInvocation) -> bool + 'static,
286        >(
287            this: *mut ffi::GDebugControllerDBus,
288            invocation: *mut ffi::GDBusMethodInvocation,
289            f: glib::ffi::gpointer,
290        ) -> glib::ffi::gboolean {
291            let f: &F = &*(f as *const F);
292            f(
293                DebugControllerDBus::from_glib_borrow(this).unsafe_cast_ref(),
294                &from_glib_borrow(invocation),
295            )
296            .into_glib()
297        }
298        unsafe {
299            let f: Box_<F> = Box_::new(f);
300            connect_raw(
301                self.as_ptr() as *mut _,
302                c"authorize".as_ptr() as *const _,
303                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
304                    authorize_trampoline::<Self, F> as *const (),
305                )),
306                Box_::into_raw(f),
307            )
308        }
309    }
310}
311
312impl<O: IsA<DebugControllerDBus>> DebugControllerDBusExt for O {}