+
+ mainloop = GLib.MainLoop()
+ dbus_obj = DbusInitializer(mainloop, dbus.SystemBus(), '/Initializer', args)
+ mainloop.run()
+
+ # After init
+ dbus_obj.remove_from_connection()
+
+class DbusInitializer(dbus.service.Object):
+ def __init__(self, looper, bus, object_path, args):
+ self.args = args
+ self.looper = looper
+ dbus.service.Object.__init__(self, bus, object_path)
+
+ @dbus.service.method("id.waydro.Initializer", in_signature='a{ss}', out_signature='', sender_keyword="sender", connection_keyword="conn")
+ def Init(self, params, sender=None, conn=None):
+ channels_cfg = tools.config.load_channels()
+ no_auth = params["system_channel"] == channels_cfg["channels"]["system_channel"] and \
+ params["vendor_channel"] == channels_cfg["channels"]["vendor_channel"]
+ if no_auth or ensure_polkit_auth(sender, conn, "id.waydro.Initializer.Init"):
+ threading.Thread(target=remote_init_server, args=(self.args, params)).start()
+ else:
+ raise PermissionError("Polkit: Authentication failed")
+
+ @dbus.service.method("id.waydro.Initializer", in_signature='', out_signature='')
+ def Done(self):
+ if is_initialized(self.args):
+ self.looper.quit()
+
+def ensure_polkit_auth(sender, conn, privilege):
+ dbus_info = dbus.Interface(conn.get_object("org.freedesktop.DBus", "/org/freedesktop/DBus/Bus", False), "org.freedesktop.DBus")
+ pid = dbus_info.GetConnectionUnixProcessID(sender)
+ polkit = dbus.Interface(dbus.SystemBus().get_object("org.freedesktop.PolicyKit1", "/org/freedesktop/PolicyKit1/Authority", False), "org.freedesktop.PolicyKit1.Authority")
+ try:
+ (is_auth, _, _) = polkit.CheckAuthorization(
+ ("unix-process", {
+ "pid": dbus.UInt32(pid, variant_level=1),
+ "start-time": dbus.UInt64(0, variant_level=1)}),
+ privilege, {"AllowUserInteraction": "true"},
+ dbus.UInt32(1),
+ "",
+ timeout=300)
+ return is_auth
+ except dbus.DBusException:
+ raise PermissionError("Polkit: Authentication timed out")