126
127
a sensible number of times
127
128
group: D-Bus Entry Group
128
129
server: D-Bus Server
129
bus: dbus.SystemBus()
131
131
def __init__(self, interface = avahi.IF_UNSPEC, name = None,
132
132
servicetype = None, port = None, TXT = None,
313
313
def enable(self):
314
314
"""Start this client's checker and timeout hooks"""
315
if getattr(self, u"enabled", False):
318
315
self.last_enabled = datetime.datetime.utcnow()
319
316
# Schedule a new checker to be started an 'interval' from now,
320
317
# and every interval from then on.
481
478
"""A Client class using D-Bus
484
dbus_object_path: dbus.ObjectPath
485
bus: dbus.SystemBus()
481
dbus_object_path: dbus.ObjectPath ; only set if self.use_dbus
487
483
# dbus.service.Object doesn't use super(), so we can't either.
898
894
class ForkingMixInWithPipe(socketserver.ForkingMixIn, object):
899
"""Like socketserver.ForkingMixIn, but also pass a pipe."""
895
"""Like socketserver.ForkingMixIn, but also pass a pipe.
897
Assumes a gobject.MainLoop event loop.
900
899
def process_request(self, request, client_address):
901
900
"""Overrides and wraps the original process_request().
906
905
super(ForkingMixInWithPipe,
907
906
self).process_request(request, client_address)
908
907
os.close(self.pipe[1]) # close write end
909
self.add_pipe(self.pipe[0])
910
def add_pipe(self, pipe):
908
# Call "handle_ipc" for both data and EOF events
909
gobject.io_add_watch(self.pipe[0],
910
gobject.IO_IN | gobject.IO_HUP,
912
def handle_ipc(source, condition):
911
913
"""Dummy function; override as necessary"""
915
918
class IPv6_TCPServer(ForkingMixInWithPipe,
920
923
enabled: Boolean; whether this server is activated yet
921
924
interface: None or a network interface name (string)
922
925
use_ipv6: Boolean; to use IPv6 or not
927
clients: set of Client objects
928
gnutls_priority GnuTLS priority string
929
use_dbus: Boolean; to emit D-Bus signals or not
924
931
def __init__(self, server_address, RequestHandlerClass,
925
interface=None, use_ipv6=True):
932
interface=None, use_ipv6=True, clients=None,
933
gnutls_priority=None, use_dbus=True):
926
935
self.interface = interface
928
937
self.address_family = socket.AF_INET6
938
self.clients = clients
939
self.use_dbus = use_dbus
940
self.gnutls_priority = gnutls_priority
929
941
socketserver.TCPServer.__init__(self, server_address,
930
942
RequestHandlerClass)
931
943
def server_bind(self):
933
945
to bind to an interface if one was specified, and also NOT to
934
946
bind to an address or port if they were not specified."""
935
947
if self.interface is not None:
936
if SO_BINDTODEVICE is None:
937
logger.error(u"SO_BINDTODEVICE does not exist;"
938
u" cannot bind to interface %s",
942
self.socket.setsockopt(socket.SOL_SOCKET,
946
except socket.error, error:
947
if error[0] == errno.EPERM:
948
logger.error(u"No permission to"
949
u" bind to interface %s",
951
elif error[0] == errno.ENOPROTOOPT:
952
logger.error(u"SO_BINDTODEVICE not available;"
953
u" cannot bind to interface %s",
949
self.socket.setsockopt(socket.SOL_SOCKET,
951
str(self.interface + u'\0'))
952
except socket.error, error:
953
if error[0] == errno.EPERM:
954
logger.error(u"No permission to"
955
u" bind to interface %s",
957
959
# Only bind(2) the socket if we really need to.
958
960
if self.server_address[0] or self.server_address[1]:
959
961
if not self.server_address[0]:
974
976
# (self.interface))
975
977
return socketserver.TCPServer.server_bind(self)
978
class MandosServer(IPv6_TCPServer):
982
clients: set of Client objects
983
gnutls_priority GnuTLS priority string
984
use_dbus: Boolean; to emit D-Bus signals or not
985
clients: set of Client objects
986
gnutls_priority GnuTLS priority string
987
use_dbus: Boolean; to emit D-Bus signals or not
989
Assumes a gobject.MainLoop event loop.
991
def __init__(self, server_address, RequestHandlerClass,
992
interface=None, use_ipv6=True, clients=None,
993
gnutls_priority=None, use_dbus=True):
995
self.clients = clients
996
if self.clients is None:
998
self.use_dbus = use_dbus
999
self.gnutls_priority = gnutls_priority
1000
IPv6_TCPServer.__init__(self, server_address,
1001
RequestHandlerClass,
1002
interface = interface,
1003
use_ipv6 = use_ipv6)
1004
978
def server_activate(self):
1005
979
if self.enabled:
1006
980
return socketserver.TCPServer.server_activate(self)
1007
981
def enable(self):
1008
982
self.enabled = True
1009
def add_pipe(self, pipe):
1010
# Call "handle_ipc" for both data and EOF events
1011
gobject.io_add_watch(pipe, gobject.IO_IN | gobject.IO_HUP,
1013
983
def handle_ipc(self, source, condition, file_objects={}):
1014
984
condition_names = {
1015
985
gobject.IO_IN: u"IN", # There is data to read.
1279
1249
global mandos_dbus_service
1280
1250
mandos_dbus_service = None
1282
tcp_server = MandosServer((server_settings[u"address"],
1283
server_settings[u"port"]),
1285
interface=server_settings[u"interface"],
1288
server_settings[u"priority"],
1253
tcp_server = IPv6_TCPServer((server_settings[u"address"],
1254
server_settings[u"port"]),
1257
server_settings[u"interface"],
1261
server_settings[u"priority"],
1290
1263
pidfilename = u"/var/run/mandos.pid"
1292
1265
pidfile = open(pidfilename, u"w")
1346
1319
client_class = Client
1348
1321
client_class = functools.partial(ClientDBus, bus = bus)
1349
tcp_server.clients.update(set(
1350
1323
client_class(name = section,
1351
1324
config= dict(client_config.items(section)))
1352
1325
for section in client_config.sections()))
1353
if not tcp_server.clients:
1354
1327
logger.warning(u"No clients defined")
1419
1392
@dbus.service.method(_interface, out_signature=u"ao")
1420
1393
def GetAllClients(self):
1422
return dbus.Array(c.dbus_object_path
1423
for c in tcp_server.clients)
1395
return dbus.Array(c.dbus_object_path for c in clients)
1425
1397
@dbus.service.method(_interface,
1426
1398
out_signature=u"a{oa{sv}}")
1429
1401
return dbus.Dictionary(
1430
1402
((c.dbus_object_path, c.GetAllProperties())
1431
for c in tcp_server.clients),
1432
1404
signature=u"oa{sv}")
1434
1406
@dbus.service.method(_interface, in_signature=u"o")
1435
1407
def RemoveClient(self, object_path):
1437
for c in tcp_server.clients:
1438
1410
if c.dbus_object_path == object_path:
1439
tcp_server.clients.remove(c)
1440
1412
c.remove_from_connection()
1441
1413
# Don't signal anything except ClientRemoved
1442
1414
c.disable(signal=False)