983
983
raise DBusPropertyNotFound("{}:{}.{}".format(
984
984
self.dbus_object_path, interface_name, property_name))
987
def _get_all_interface_names(cls):
988
"""Get a sequence of all interfaces supported by an object"""
989
return (name for name in set(getattr(getattr(x, attr),
990
"_dbus_interface", None)
991
for x in (inspect.getmro(cls))
986
995
@dbus.service.method(dbus.PROPERTIES_IFACE,
987
996
in_signature="ss",
988
997
out_signature="v")
1118
1127
exc_info=error)
1119
1128
return xmlstring
1131
dbus.OBJECT_MANAGER_IFACE
1132
except AttributeError:
1133
dbus.OBJECT_MANAGER_IFACE = "org.freedesktop.DBus.ObjectManager"
1135
class DBusObjectWithObjectManager(DBusObjectWithAnnotations):
1136
"""A D-Bus object with an ObjectManager.
1138
Classes inheriting from this exposes the standard
1139
GetManagedObjects call and the InterfacesAdded and
1140
InterfacesRemoved signals on the standard
1141
"org.freedesktop.DBus.ObjectManager" interface.
1143
Note: No signals are sent automatically; they must be sent
1146
@dbus.service.method(dbus.OBJECT_MANAGER_IFACE,
1147
out_signature = "a{oa{sa{sv}}}")
1148
def GetManagedObjects(self):
1149
"""This function must be overridden"""
1150
raise NotImplementedError()
1152
@dbus.service.signal(dbus.OBJECT_MANAGER_IFACE,
1153
signature = "oa{sa{sv}}")
1154
def InterfacesAdded(self, object_path, interfaces_and_properties):
1157
@dbus.service.signal(dbus.OBJECT_MANAGER_IFACE,
1159
def InterfacesRemoved(self, object_path, interfaces):
1162
@dbus.service.method(dbus.INTROSPECTABLE_IFACE,
1163
out_signature = "s",
1164
path_keyword = 'object_path',
1165
connection_keyword = 'connection')
1166
def Introspect(self, object_path, connection):
1167
"""Overloading of standard D-Bus method.
1169
Override return argument name of GetManagedObjects to be
1170
"objpath_interfaces_and_properties"
1172
xmlstring = DBusObjectWithAnnotations(self, object_path,
1175
document = xml.dom.minidom.parseString(xmlstring)
1177
for if_tag in document.getElementsByTagName("interface"):
1178
# Fix argument name for the GetManagedObjects method
1179
if (if_tag.getAttribute("name")
1180
== dbus.OBJECT_MANAGER_IFACE):
1181
for cn in if_tag.getElementsByTagName("method"):
1182
if (cn.getAttribute("name")
1183
== "GetManagedObjects"):
1184
for arg in cn.getElementsByTagName("arg"):
1185
if (arg.getAttribute("direction")
1189
"objpath_interfaces"
1191
xmlstring = document.toxml("utf-8")
1193
except (AttributeError, xml.dom.DOMException,
1194
xml.parsers.expat.ExpatError) as error:
1195
logger.error("Failed to override Introspection method",
1122
1199
def datetime_to_dbus(dt, variant_level=0):
1123
1200
"""Convert a UTC datetime.datetime() to a D-Bus type."""
2911
@dbus_annotations({"org.freedesktop.DBus.Deprecated":
2834
2913
@dbus.service.signal(_interface, signature="os")
2835
2914
def ClientRemoved(self, objpath, name):
2918
@dbus_annotations({"org.freedesktop.DBus.Deprecated":
2839
2920
@dbus.service.method(_interface, out_signature="ao")
2840
2921
def GetAllClients(self):
2842
2923
return dbus.Array(c.dbus_object_path for c in
2843
2924
tcp_server.clients.itervalues())
2926
@dbus_annotations({"org.freedesktop.DBus.Deprecated":
2845
2928
@dbus.service.method(_interface,
2846
2929
out_signature="a{oa{sv}}")
2847
2930
def GetAllClientsWithProperties(self):
2849
2932
return dbus.Dictionary(
2850
{ c.dbus_object_path: c.GetAll("")
2933
{ c.dbus_object_path: c.GetAll(
2934
"se.recompile.Mandos.Client")
2851
2935
for c in tcp_server.clients.itervalues() },
2852
2936
signature="oa{sv}")
2858
2942
if c.dbus_object_path == object_path:
2859
2943
del tcp_server.clients[c.name]
2860
2944
c.remove_from_connection()
2861
# Don't signal anything except ClientRemoved
2945
# Don't signal the disabling
2862
2946
c.disable(quiet=True)
2864
self.ClientRemoved(object_path, c.name)
2947
# Emit D-Bus signal for removal
2948
self.client_removed_signal(c)
2866
2950
raise KeyError(object_path)
2954
@dbus.service.method(dbus.OBJECT_MANAGER_IFACE,
2955
out_signature = "a{oa{sa{sv}}}")
2956
def GetManagedObjects(self):
2958
return dbus.Dictionary(
2959
{ client.dbus_object_path:
2961
{ interface: client.GetAll(interface)
2963
client._get_all_interface_names()})
2964
for client in tcp_server.clients.values()})
2966
def client_added_signal(self, client):
2967
"""Send the new standard signal and the old signal"""
2969
# New standard signal
2970
self.InterfacesAdded(
2971
client.dbus_object_path,
2973
{ interface: client.GetAll(interface)
2975
client._get_all_interface_names()}))
2977
self.ClientAdded(client.dbus_object_path)
2979
def client_removed_signal(self, client):
2980
"""Send the new standard signal and the old signal"""
2982
# New standard signal
2983
self.InterfacesRemoved(
2984
client.dbus_object_path,
2985
client._get_all_interface_names())
2987
self.ClientRemoved(client.dbus_object_path,
2870
2990
mandos_dbus_service = MandosDBusService()
2936
3056
name, client = tcp_server.clients.popitem()
2938
3058
client.remove_from_connection()
2939
# Don't signal anything except ClientRemoved
3059
# Don't signal the disabling
2940
3060
client.disable(quiet=True)
2943
mandos_dbus_service.ClientRemoved(
2944
client.dbus_object_path, client.name)
3061
# Emit D-Bus signal for removal
3062
mandos_dbus_service.client_removed_signal(client)
2945
3063
client_settings.clear()
2947
3065
atexit.register(cleanup)
2949
3067
for client in tcp_server.clients.itervalues():
2952
mandos_dbus_service.ClientAdded(client.dbus_object_path)
3069
# Emit D-Bus signal for adding
3070
mandos_dbus_service.client_added_signal(client)
2953
3071
# Need to initiate checking of clients
2954
3072
if client.enabled:
2955
3073
client.init_checker()