/mandos/trunk

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/trunk

« back to all changes in this revision

Viewing changes to mandos

  • Committer: Teddy Hogeborn
  • Date: 2009-04-16 21:33:49 UTC
  • Revision ID: teddy@fukt.bsnet.se-20090416213349-dwtllm8tvh2i0xbk
* mandos: Minor doc string fixes.
  (SO_BINDTODEVICE): Do not guess if not found.
  (IPv6_TCPServer.server_bind): Handle case where SO_BINDTODEVICE is
                                not available.

Show diffs side-by-side

added added

removed removed

Lines of Context:
312
312
    
313
313
    def enable(self):
314
314
        """Start this client's checker and timeout hooks"""
315
 
        if getattr(self, u"enabled", False):
316
 
            # Already enabled
317
 
            return
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.
896
893
 
897
894
 
898
895
class ForkingMixInWithPipe(socketserver.ForkingMixIn, object):
899
 
    """Like socketserver.ForkingMixIn, but also pass a pipe."""
 
896
    """Like socketserver.ForkingMixIn, but also pass a pipe.
 
897
    
 
898
    Assumes a gobject.MainLoop event loop.
 
899
    """
900
900
    def process_request(self, request, client_address):
901
901
        """Overrides and wraps the original process_request().
902
902
        
906
906
        super(ForkingMixInWithPipe,
907
907
              self).process_request(request, client_address)
908
908
        os.close(self.pipe[1])  # close write end
909
 
        self.add_pipe(self.pipe[0])
910
 
    def add_pipe(self, pipe):
 
909
        # Call "handle_ipc" for both data and EOF events
 
910
        gobject.io_add_watch(self.pipe[0],
 
911
                             gobject.IO_IN | gobject.IO_HUP,
 
912
                             self.handle_ipc)
 
913
    def handle_ipc(source, condition):
911
914
        """Dummy function; override as necessary"""
912
 
        os.close(pipe)
 
915
        os.close(source)
 
916
        return False
913
917
 
914
918
 
915
919
class IPv6_TCPServer(ForkingMixInWithPipe,
920
924
        enabled:        Boolean; whether this server is activated yet
921
925
        interface:      None or a network interface name (string)
922
926
        use_ipv6:       Boolean; to use IPv6 or not
 
927
        ----
 
928
        clients:        set of Client objects
 
929
        gnutls_priority GnuTLS priority string
 
930
        use_dbus:       Boolean; to emit D-Bus signals or not
923
931
    """
924
932
    def __init__(self, server_address, RequestHandlerClass,
925
 
                 interface=None, use_ipv6=True):
 
933
                 interface=None, use_ipv6=True, clients=None,
 
934
                 gnutls_priority=None, use_dbus=True):
 
935
        self.enabled = False
926
936
        self.interface = interface
927
937
        if use_ipv6:
928
938
            self.address_family = socket.AF_INET6
 
939
        self.clients = clients
 
940
        self.use_dbus = use_dbus
 
941
        self.gnutls_priority = gnutls_priority
929
942
        socketserver.TCPServer.__init__(self, server_address,
930
943
                                        RequestHandlerClass)
931
944
    def server_bind(self):
973
986
#                                            if_nametoindex
974
987
#                                            (self.interface))
975
988
            return socketserver.TCPServer.server_bind(self)
976
 
 
977
 
 
978
 
class MandosServer(IPv6_TCPServer):
979
 
    """Mandos server.
980
 
    
981
 
    Attributes:
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
988
 
    
989
 
    Assumes a gobject.MainLoop event loop.
990
 
    """
991
 
    def __init__(self, server_address, RequestHandlerClass,
992
 
                 interface=None, use_ipv6=True, clients=None,
993
 
                 gnutls_priority=None, use_dbus=True):
994
 
        self.enabled = False
995
 
        self.clients = clients
996
 
        if self.clients is None:
997
 
            self.clients = set()
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
989
    def server_activate(self):
1005
990
        if self.enabled:
1006
991
            return socketserver.TCPServer.server_activate(self)
1007
992
    def enable(self):
1008
993
        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,
1012
 
                             self.handle_ipc)
1013
994
    def handle_ipc(self, source, condition, file_objects={}):
1014
995
        condition_names = {
1015
996
            gobject.IO_IN: u"IN",   # There is data to read.
1279
1260
    global mandos_dbus_service
1280
1261
    mandos_dbus_service = None
1281
1262
    
1282
 
    tcp_server = MandosServer((server_settings[u"address"],
1283
 
                               server_settings[u"port"]),
1284
 
                              ClientHandler,
1285
 
                              interface=server_settings[u"interface"],
1286
 
                              use_ipv6=use_ipv6,
1287
 
                              gnutls_priority=
1288
 
                              server_settings[u"priority"],
1289
 
                              use_dbus=use_dbus)
 
1263
    clients = set()
 
1264
    tcp_server = IPv6_TCPServer((server_settings[u"address"],
 
1265
                                 server_settings[u"port"]),
 
1266
                                ClientHandler,
 
1267
                                interface=
 
1268
                                server_settings[u"interface"],
 
1269
                                use_ipv6=use_ipv6,
 
1270
                                clients=clients,
 
1271
                                gnutls_priority=
 
1272
                                server_settings[u"priority"],
 
1273
                                use_dbus=use_dbus)
1290
1274
    pidfilename = u"/var/run/mandos.pid"
1291
1275
    try:
1292
1276
        pidfile = open(pidfilename, u"w")
1346
1330
    client_class = Client
1347
1331
    if use_dbus:
1348
1332
        client_class = functools.partial(ClientDBus, bus = bus)
1349
 
    tcp_server.clients.update(set(
 
1333
    clients.update(set(
1350
1334
            client_class(name = section,
1351
1335
                         config= dict(client_config.items(section)))
1352
1336
            for section in client_config.sections()))
1353
 
    if not tcp_server.clients:
 
1337
    if not clients:
1354
1338
        logger.warning(u"No clients defined")
1355
1339
    
1356
1340
    if debug:
1382
1366
        "Cleanup function; run on exit"
1383
1367
        service.cleanup()
1384
1368
        
1385
 
        while tcp_server.clients:
1386
 
            client = tcp_server.clients.pop()
 
1369
        while clients:
 
1370
            client = clients.pop()
1387
1371
            client.disable_hook = None
1388
1372
            client.disable()
1389
1373
    
1419
1403
            @dbus.service.method(_interface, out_signature=u"ao")
1420
1404
            def GetAllClients(self):
1421
1405
                "D-Bus method"
1422
 
                return dbus.Array(c.dbus_object_path
1423
 
                                  for c in tcp_server.clients)
 
1406
                return dbus.Array(c.dbus_object_path for c in clients)
1424
1407
            
1425
1408
            @dbus.service.method(_interface,
1426
1409
                                 out_signature=u"a{oa{sv}}")
1428
1411
                "D-Bus method"
1429
1412
                return dbus.Dictionary(
1430
1413
                    ((c.dbus_object_path, c.GetAllProperties())
1431
 
                     for c in tcp_server.clients),
 
1414
                     for c in clients),
1432
1415
                    signature=u"oa{sv}")
1433
1416
            
1434
1417
            @dbus.service.method(_interface, in_signature=u"o")
1435
1418
            def RemoveClient(self, object_path):
1436
1419
                "D-Bus method"
1437
 
                for c in tcp_server.clients:
 
1420
                for c in clients:
1438
1421
                    if c.dbus_object_path == object_path:
1439
 
                        tcp_server.clients.remove(c)
 
1422
                        clients.remove(c)
1440
1423
                        c.remove_from_connection()
1441
1424
                        # Don't signal anything except ClientRemoved
1442
1425
                        c.disable(signal=False)
1449
1432
        
1450
1433
        mandos_dbus_service = MandosDBusService()
1451
1434
    
1452
 
    for client in tcp_server.clients:
 
1435
    for client in clients:
1453
1436
        if use_dbus:
1454
1437
            # Emit D-Bus signal
1455
1438
            mandos_dbus_service.ClientAdded(client.dbus_object_path,