/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 06:47:28 UTC
  • Revision ID: teddy@fukt.bsnet.se-20090416064728-c3d36mvgxo5q9aoh
* mandos: Import "SocketServer" as "socketserver" and "ConfigParser"
          as "configparser".  All users changed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
# This program is partly derived from an example program for an Avahi
7
7
# service publisher, downloaded from
8
8
# <http://avahi.org/wiki/PythonPublishExample>.  This includes the
9
 
# methods "add", "remove", "server_state_changed",
10
 
# "entry_group_state_changed", "cleanup", and "activate" in the
11
 
# "AvahiService" class, and some lines in "main".
 
9
# methods "add" and "remove" in the "AvahiService" class, the
 
10
# "server_state_changed" and "entry_group_state_changed" functions,
 
11
# and some lines in "main".
12
12
13
13
# Everything else is
14
14
# Copyright © 2008,2009 Teddy Hogeborn
58
58
from contextlib import closing
59
59
import struct
60
60
import fcntl
61
 
import functools
62
61
 
63
62
import dbus
64
63
import dbus.service
74
73
    try:
75
74
        from IN import SO_BINDTODEVICE
76
75
    except ImportError:
77
 
        SO_BINDTODEVICE = None
78
 
 
79
 
 
80
 
version = "1.0.11"
 
76
        # From /usr/include/asm/socket.h
 
77
        SO_BINDTODEVICE = 25
 
78
 
 
79
 
 
80
version = "1.0.8"
81
81
 
82
82
logger = logging.Logger(u'mandos')
83
83
syslogger = (logging.handlers.SysLogHandler
124
124
    max_renames: integer; maximum number of renames
125
125
    rename_count: integer; counter so we only rename after collisions
126
126
                  a sensible number of times
127
 
    group: D-Bus Entry Group
128
 
    server: D-Bus Server
129
 
    bus: dbus.SystemBus()
130
127
    """
131
128
    def __init__(self, interface = avahi.IF_UNSPEC, name = None,
132
129
                 servicetype = None, port = None, TXT = None,
133
130
                 domain = u"", host = u"", max_renames = 32768,
134
 
                 protocol = avahi.PROTO_UNSPEC, bus = None):
 
131
                 protocol = avahi.PROTO_UNSPEC):
135
132
        self.interface = interface
136
133
        self.name = name
137
134
        self.type = servicetype
142
139
        self.rename_count = 0
143
140
        self.max_renames = max_renames
144
141
        self.protocol = protocol
145
 
        self.group = None       # our entry group
146
 
        self.server = None
147
 
        self.bus = bus
148
142
    def rename(self):
149
143
        """Derived from the Avahi example code"""
150
144
        if self.rename_count >= self.max_renames:
152
146
                            u" after %i retries, exiting.",
153
147
                            self.rename_count)
154
148
            raise AvahiServiceError(u"Too many renames")
155
 
        self.name = self.server.GetAlternativeServiceName(self.name)
 
149
        self.name = server.GetAlternativeServiceName(self.name)
156
150
        logger.info(u"Changing Zeroconf service name to %r ...",
157
 
                    unicode(self.name))
 
151
                    self.name)
158
152
        syslogger.setFormatter(logging.Formatter
159
153
                               (u'Mandos (%s) [%%(process)d]:'
160
154
                                u' %%(levelname)s: %%(message)s'
164
158
        self.rename_count += 1
165
159
    def remove(self):
166
160
        """Derived from the Avahi example code"""
167
 
        if self.group is not None:
168
 
            self.group.Reset()
 
161
        if group is not None:
 
162
            group.Reset()
169
163
    def add(self):
170
164
        """Derived from the Avahi example code"""
171
 
        if self.group is None:
172
 
            self.group = dbus.Interface(
173
 
                self.bus.get_object(avahi.DBUS_NAME,
174
 
                                    self.server.EntryGroupNew()),
175
 
                avahi.DBUS_INTERFACE_ENTRY_GROUP)
176
 
            self.group.connect_to_signal('StateChanged',
177
 
                                         self.entry_group_state_changed)
 
165
        global group
 
166
        if group is None:
 
167
            group = dbus.Interface(bus.get_object
 
168
                                   (avahi.DBUS_NAME,
 
169
                                    server.EntryGroupNew()),
 
170
                                   avahi.DBUS_INTERFACE_ENTRY_GROUP)
 
171
            group.connect_to_signal('StateChanged',
 
172
                                    entry_group_state_changed)
178
173
        logger.debug(u"Adding Zeroconf service '%s' of type '%s' ...",
179
 
                     self.name, self.type)
180
 
        self.group.AddService(
181
 
            self.interface,
182
 
            self.protocol,
183
 
            dbus.UInt32(0),     # flags
184
 
            self.name, self.type,
185
 
            self.domain, self.host,
186
 
            dbus.UInt16(self.port),
187
 
            avahi.string_array_to_txt_array(self.TXT))
188
 
        self.group.Commit()
189
 
    def entry_group_state_changed(self, state, error):
190
 
        """Derived from the Avahi example code"""
191
 
        logger.debug(u"Avahi state change: %i", state)
192
 
        
193
 
        if state == avahi.ENTRY_GROUP_ESTABLISHED:
194
 
            logger.debug(u"Zeroconf service established.")
195
 
        elif state == avahi.ENTRY_GROUP_COLLISION:
196
 
            logger.warning(u"Zeroconf service name collision.")
197
 
            self.rename()
198
 
        elif state == avahi.ENTRY_GROUP_FAILURE:
199
 
            logger.critical(u"Avahi: Error in group state changed %s",
200
 
                            unicode(error))
201
 
            raise AvahiGroupError(u"State changed: %s"
202
 
                                  % unicode(error))
203
 
    def cleanup(self):
204
 
        """Derived from the Avahi example code"""
205
 
        if self.group is not None:
206
 
            self.group.Free()
207
 
            self.group = None
208
 
    def server_state_changed(self, state):
209
 
        """Derived from the Avahi example code"""
210
 
        if state == avahi.SERVER_COLLISION:
211
 
            logger.error(u"Zeroconf server name collision")
212
 
            self.remove()
213
 
        elif state == avahi.SERVER_RUNNING:
214
 
            self.add()
215
 
    def activate(self):
216
 
        """Derived from the Avahi example code"""
217
 
        if self.server is None:
218
 
            self.server = dbus.Interface(
219
 
                self.bus.get_object(avahi.DBUS_NAME,
220
 
                                    avahi.DBUS_PATH_SERVER),
221
 
                avahi.DBUS_INTERFACE_SERVER)
222
 
        self.server.connect_to_signal(u"StateChanged",
223
 
                                 self.server_state_changed)
224
 
        self.server_state_changed(self.server.GetState())
 
174
                     service.name, service.type)
 
175
        group.AddService(
 
176
                self.interface,         # interface
 
177
                self.protocol,          # protocol
 
178
                dbus.UInt32(0),         # flags
 
179
                self.name, self.type,
 
180
                self.domain, self.host,
 
181
                dbus.UInt16(self.port),
 
182
                avahi.string_array_to_txt_array(self.TXT))
 
183
        group.Commit()
 
184
 
 
185
# From the Avahi example code:
 
186
group = None                            # our entry group
 
187
# End of Avahi example code
 
188
 
 
189
 
 
190
def _datetime_to_dbus(dt, variant_level=0):
 
191
    """Convert a UTC datetime.datetime() to a D-Bus type."""
 
192
    return dbus.String(dt.isoformat(), variant_level=variant_level)
225
193
 
226
194
 
227
195
class Client(object):
312
280
    
313
281
    def enable(self):
314
282
        """Start this client's checker and timeout hooks"""
315
 
        if getattr(self, u"enabled", False):
316
 
            # Already enabled
317
 
            return
318
283
        self.last_enabled = datetime.datetime.utcnow()
319
284
        # Schedule a new checker to be started an 'interval' from now,
320
285
        # and every interval from then on.
481
446
    """A Client class using D-Bus
482
447
    
483
448
    Attributes:
484
 
    dbus_object_path: dbus.ObjectPath
485
 
    bus: dbus.SystemBus()
 
449
    dbus_object_path: dbus.ObjectPath ; only set if self.use_dbus
486
450
    """
487
451
    # dbus.service.Object doesn't use super(), so we can't either.
488
452
    
489
 
    def __init__(self, bus = None, *args, **kwargs):
490
 
        self.bus = bus
 
453
    def __init__(self, *args, **kwargs):
491
454
        Client.__init__(self, *args, **kwargs)
492
455
        # Only now, when this client is initialized, can it show up on
493
456
        # the D-Bus
494
457
        self.dbus_object_path = (dbus.ObjectPath
495
458
                                 (u"/clients/"
496
459
                                  + self.name.replace(u".", u"_")))
497
 
        dbus.service.Object.__init__(self, self.bus,
 
460
        dbus.service.Object.__init__(self, bus,
498
461
                                     self.dbus_object_path)
499
 
    
500
 
    @staticmethod
501
 
    def _datetime_to_dbus(dt, variant_level=0):
502
 
        """Convert a UTC datetime.datetime() to a D-Bus type."""
503
 
        return dbus.String(dt.isoformat(),
504
 
                           variant_level=variant_level)
505
 
    
506
462
    def enable(self):
507
463
        oldstate = getattr(self, u"enabled", False)
508
464
        r = Client.enable(self)
510
466
            # Emit D-Bus signals
511
467
            self.PropertyChanged(dbus.String(u"enabled"),
512
468
                                 dbus.Boolean(True, variant_level=1))
513
 
            self.PropertyChanged(
514
 
                dbus.String(u"last_enabled"),
515
 
                self._datetime_to_dbus(self.last_enabled,
516
 
                                       variant_level=1))
 
469
            self.PropertyChanged(dbus.String(u"last_enabled"),
 
470
                                 (_datetime_to_dbus(self.last_enabled,
 
471
                                                    variant_level=1)))
517
472
        return r
518
473
    
519
474
    def disable(self, signal = True):
561
516
        # Emit D-Bus signal
562
517
        self.PropertyChanged(
563
518
            dbus.String(u"last_checked_ok"),
564
 
            (self._datetime_to_dbus(self.last_checked_ok,
565
 
                                    variant_level=1)))
 
519
            (_datetime_to_dbus(self.last_checked_ok,
 
520
                               variant_level=1)))
566
521
        return r
567
522
    
568
523
    def start_checker(self, *args, **kwargs):
623
578
                dbus.String(u"host"):
624
579
                    dbus.String(self.host, variant_level=1),
625
580
                dbus.String(u"created"):
626
 
                    self._datetime_to_dbus(self.created,
627
 
                                           variant_level=1),
 
581
                    _datetime_to_dbus(self.created, variant_level=1),
628
582
                dbus.String(u"last_enabled"):
629
 
                    (self._datetime_to_dbus(self.last_enabled,
630
 
                                            variant_level=1)
 
583
                    (_datetime_to_dbus(self.last_enabled,
 
584
                                       variant_level=1)
631
585
                     if self.last_enabled is not None
632
586
                     else dbus.Boolean(False, variant_level=1)),
633
587
                dbus.String(u"enabled"):
634
588
                    dbus.Boolean(self.enabled, variant_level=1),
635
589
                dbus.String(u"last_checked_ok"):
636
 
                    (self._datetime_to_dbus(self.last_checked_ok,
637
 
                                            variant_level=1)
 
590
                    (_datetime_to_dbus(self.last_checked_ok,
 
591
                                       variant_level=1)
638
592
                     if self.last_checked_ok is not None
639
593
                     else dbus.Boolean (False, variant_level=1)),
640
594
                dbus.String(u"timeout"):
811
765
                    client = c
812
766
                    break
813
767
            else:
814
 
                ipc.write(u"NOTFOUND %s %s\n"
815
 
                          % (fpr, unicode(self.client_address)))
 
768
                ipc.write(u"NOTFOUND %s\n" % fpr)
816
769
                session.bye()
817
770
                return
818
771
            # Have to check if client.still_valid(), since it is
897
850
 
898
851
 
899
852
class ForkingMixInWithPipe(socketserver.ForkingMixIn, object):
900
 
    """Like socketserver.ForkingMixIn, but also pass a pipe."""
 
853
    """Like socketserver.ForkingMixIn, but also pass a pipe.
 
854
    
 
855
    Assumes a gobject.MainLoop event loop.
 
856
    """
901
857
    def process_request(self, request, client_address):
902
858
        """Overrides and wraps the original process_request().
903
859
        
904
 
        This function creates a new pipe in self.pipe
 
860
        This function creates a new pipe in self.pipe 
905
861
        """
906
862
        self.pipe = os.pipe()
907
863
        super(ForkingMixInWithPipe,
908
864
              self).process_request(request, client_address)
909
865
        os.close(self.pipe[1])  # close write end
910
 
        self.add_pipe(self.pipe[0])
911
 
    def add_pipe(self, pipe):
 
866
        # Call "handle_ipc" for both data and EOF events
 
867
        gobject.io_add_watch(self.pipe[0],
 
868
                             gobject.IO_IN | gobject.IO_HUP,
 
869
                             self.handle_ipc)
 
870
    def handle_ipc(source, condition):
912
871
        """Dummy function; override as necessary"""
913
 
        os.close(pipe)
 
872
        os.close(source)
 
873
        return False
914
874
 
915
875
 
916
876
class IPv6_TCPServer(ForkingMixInWithPipe,
921
881
        enabled:        Boolean; whether this server is activated yet
922
882
        interface:      None or a network interface name (string)
923
883
        use_ipv6:       Boolean; to use IPv6 or not
 
884
        ----
 
885
        clients:        set of Client objects
 
886
        gnutls_priority GnuTLS priority string
 
887
        use_dbus:       Boolean; to emit D-Bus signals or not
924
888
    """
925
889
    def __init__(self, server_address, RequestHandlerClass,
926
 
                 interface=None, use_ipv6=True):
 
890
                 interface=None, use_ipv6=True, clients=None,
 
891
                 gnutls_priority=None, use_dbus=True):
 
892
        self.enabled = False
927
893
        self.interface = interface
928
894
        if use_ipv6:
929
895
            self.address_family = socket.AF_INET6
 
896
        self.clients = clients
 
897
        self.use_dbus = use_dbus
 
898
        self.gnutls_priority = gnutls_priority
930
899
        socketserver.TCPServer.__init__(self, server_address,
931
900
                                        RequestHandlerClass)
932
901
    def server_bind(self):
934
903
        to bind to an interface if one was specified, and also NOT to
935
904
        bind to an address or port if they were not specified."""
936
905
        if self.interface is not None:
937
 
            if SO_BINDTODEVICE is None:
938
 
                logger.error(u"SO_BINDTODEVICE does not exist;"
939
 
                             u" cannot bind to interface %s",
940
 
                             self.interface)
941
 
            else:
942
 
                try:
943
 
                    self.socket.setsockopt(socket.SOL_SOCKET,
944
 
                                           SO_BINDTODEVICE,
945
 
                                           str(self.interface
946
 
                                               + u'\0'))
947
 
                except socket.error, error:
948
 
                    if error[0] == errno.EPERM:
949
 
                        logger.error(u"No permission to"
950
 
                                     u" bind to interface %s",
951
 
                                     self.interface)
952
 
                    elif error[0] == errno.ENOPROTOOPT:
953
 
                        logger.error(u"SO_BINDTODEVICE not available;"
954
 
                                     u" cannot bind to interface %s",
955
 
                                     self.interface)
956
 
                    else:
957
 
                        raise
 
906
            try:
 
907
                self.socket.setsockopt(socket.SOL_SOCKET,
 
908
                                       SO_BINDTODEVICE,
 
909
                                       str(self.interface + u'\0'))
 
910
            except socket.error, error:
 
911
                if error[0] == errno.EPERM:
 
912
                    logger.error(u"No permission to"
 
913
                                 u" bind to interface %s",
 
914
                                 self.interface)
 
915
                else:
 
916
                    raise
958
917
        # Only bind(2) the socket if we really need to.
959
918
        if self.server_address[0] or self.server_address[1]:
960
919
            if not self.server_address[0]:
974
933
#                                            if_nametoindex
975
934
#                                            (self.interface))
976
935
            return socketserver.TCPServer.server_bind(self)
977
 
 
978
 
 
979
 
class MandosServer(IPv6_TCPServer):
980
 
    """Mandos server.
981
 
    
982
 
    Attributes:
983
 
        clients:        set of Client objects
984
 
        gnutls_priority GnuTLS priority string
985
 
        use_dbus:       Boolean; to emit D-Bus signals or not
986
 
        clients:        set of Client objects
987
 
        gnutls_priority GnuTLS priority string
988
 
        use_dbus:       Boolean; to emit D-Bus signals or not
989
 
    
990
 
    Assumes a gobject.MainLoop event loop.
991
 
    """
992
 
    def __init__(self, server_address, RequestHandlerClass,
993
 
                 interface=None, use_ipv6=True, clients=None,
994
 
                 gnutls_priority=None, use_dbus=True):
995
 
        self.enabled = False
996
 
        self.clients = clients
997
 
        if self.clients is None:
998
 
            self.clients = set()
999
 
        self.use_dbus = use_dbus
1000
 
        self.gnutls_priority = gnutls_priority
1001
 
        IPv6_TCPServer.__init__(self, server_address,
1002
 
                                RequestHandlerClass,
1003
 
                                interface = interface,
1004
 
                                use_ipv6 = use_ipv6)
1005
936
    def server_activate(self):
1006
937
        if self.enabled:
1007
938
            return socketserver.TCPServer.server_activate(self)
1008
939
    def enable(self):
1009
940
        self.enabled = True
1010
 
    def add_pipe(self, pipe):
1011
 
        # Call "handle_ipc" for both data and EOF events
1012
 
        gobject.io_add_watch(pipe, gobject.IO_IN | gobject.IO_HUP,
1013
 
                             self.handle_ipc)
1014
941
    def handle_ipc(self, source, condition, file_objects={}):
1015
942
        condition_names = {
1016
943
            gobject.IO_IN: u"IN",   # There is data to read.
1122
1049
    return timevalue
1123
1050
 
1124
1051
 
 
1052
def server_state_changed(state):
 
1053
    """Derived from the Avahi example code"""
 
1054
    if state == avahi.SERVER_COLLISION:
 
1055
        logger.error(u"Zeroconf server name collision")
 
1056
        service.remove()
 
1057
    elif state == avahi.SERVER_RUNNING:
 
1058
        service.add()
 
1059
 
 
1060
 
 
1061
def entry_group_state_changed(state, error):
 
1062
    """Derived from the Avahi example code"""
 
1063
    logger.debug(u"Avahi state change: %i", state)
 
1064
    
 
1065
    if state == avahi.ENTRY_GROUP_ESTABLISHED:
 
1066
        logger.debug(u"Zeroconf service established.")
 
1067
    elif state == avahi.ENTRY_GROUP_COLLISION:
 
1068
        logger.warning(u"Zeroconf service name collision.")
 
1069
        service.rename()
 
1070
    elif state == avahi.ENTRY_GROUP_FAILURE:
 
1071
        logger.critical(u"Avahi: Error in group state changed %s",
 
1072
                        unicode(error))
 
1073
        raise AvahiGroupError(u"State changed: %s" % unicode(error))
 
1074
 
1125
1075
def if_nametoindex(interface):
1126
1076
    """Call the C function if_nametoindex(), or equivalent
1127
1077
    
1280
1230
    global mandos_dbus_service
1281
1231
    mandos_dbus_service = None
1282
1232
    
1283
 
    tcp_server = MandosServer((server_settings[u"address"],
1284
 
                               server_settings[u"port"]),
1285
 
                              ClientHandler,
1286
 
                              interface=server_settings[u"interface"],
1287
 
                              use_ipv6=use_ipv6,
1288
 
                              gnutls_priority=
1289
 
                              server_settings[u"priority"],
1290
 
                              use_dbus=use_dbus)
 
1233
    clients = set()
 
1234
    tcp_server = IPv6_TCPServer((server_settings[u"address"],
 
1235
                                 server_settings[u"port"]),
 
1236
                                ClientHandler,
 
1237
                                interface=
 
1238
                                server_settings[u"interface"],
 
1239
                                use_ipv6=use_ipv6,
 
1240
                                clients=clients,
 
1241
                                gnutls_priority=
 
1242
                                server_settings[u"priority"],
 
1243
                                use_dbus=use_dbus)
1291
1244
    pidfilename = u"/var/run/mandos.pid"
1292
1245
    try:
1293
1246
        pidfile = open(pidfilename, u"w")
1328
1281
        (gnutls.library.functions
1329
1282
         .gnutls_global_set_log_function(debug_gnutls))
1330
1283
    
 
1284
    global service
 
1285
    protocol = avahi.PROTO_INET6 if use_ipv6 else avahi.PROTO_INET
 
1286
    service = AvahiService(name = server_settings[u"servicename"],
 
1287
                           servicetype = u"_mandos._tcp",
 
1288
                           protocol = protocol)
 
1289
    if server_settings["interface"]:
 
1290
        service.interface = (if_nametoindex
 
1291
                             (str(server_settings[u"interface"])))
 
1292
    
1331
1293
    global main_loop
 
1294
    global bus
 
1295
    global server
1332
1296
    # From the Avahi example code
1333
1297
    DBusGMainLoop(set_as_default=True )
1334
1298
    main_loop = gobject.MainLoop()
1335
1299
    bus = dbus.SystemBus()
 
1300
    server = dbus.Interface(bus.get_object(avahi.DBUS_NAME,
 
1301
                                           avahi.DBUS_PATH_SERVER),
 
1302
                            avahi.DBUS_INTERFACE_SERVER)
1336
1303
    # End of Avahi example code
1337
1304
    if use_dbus:
1338
1305
        bus_name = dbus.service.BusName(u"se.bsnet.fukt.Mandos", bus)
1339
 
    protocol = avahi.PROTO_INET6 if use_ipv6 else avahi.PROTO_INET
1340
 
    service = AvahiService(name = server_settings[u"servicename"],
1341
 
                           servicetype = u"_mandos._tcp",
1342
 
                           protocol = protocol, bus = bus)
1343
 
    if server_settings["interface"]:
1344
 
        service.interface = (if_nametoindex
1345
 
                             (str(server_settings[u"interface"])))
1346
1306
    
1347
1307
    client_class = Client
1348
1308
    if use_dbus:
1349
 
        client_class = functools.partial(ClientDBus, bus = bus)
1350
 
    tcp_server.clients.update(set(
 
1309
        client_class = ClientDBus
 
1310
    clients.update(set(
1351
1311
            client_class(name = section,
1352
1312
                         config= dict(client_config.items(section)))
1353
1313
            for section in client_config.sections()))
1354
 
    if not tcp_server.clients:
 
1314
    if not clients:
1355
1315
        logger.warning(u"No clients defined")
1356
1316
    
1357
1317
    if debug:
1381
1341
    
1382
1342
    def cleanup():
1383
1343
        "Cleanup function; run on exit"
1384
 
        service.cleanup()
 
1344
        global group
 
1345
        # From the Avahi example code
 
1346
        if not group is None:
 
1347
            group.Free()
 
1348
            group = None
 
1349
        # End of Avahi example code
1385
1350
        
1386
 
        while tcp_server.clients:
1387
 
            client = tcp_server.clients.pop()
 
1351
        while clients:
 
1352
            client = clients.pop()
1388
1353
            client.disable_hook = None
1389
1354
            client.disable()
1390
1355
    
1420
1385
            @dbus.service.method(_interface, out_signature=u"ao")
1421
1386
            def GetAllClients(self):
1422
1387
                "D-Bus method"
1423
 
                return dbus.Array(c.dbus_object_path
1424
 
                                  for c in tcp_server.clients)
 
1388
                return dbus.Array(c.dbus_object_path for c in clients)
1425
1389
            
1426
1390
            @dbus.service.method(_interface,
1427
1391
                                 out_signature=u"a{oa{sv}}")
1429
1393
                "D-Bus method"
1430
1394
                return dbus.Dictionary(
1431
1395
                    ((c.dbus_object_path, c.GetAllProperties())
1432
 
                     for c in tcp_server.clients),
 
1396
                     for c in clients),
1433
1397
                    signature=u"oa{sv}")
1434
1398
            
1435
1399
            @dbus.service.method(_interface, in_signature=u"o")
1436
1400
            def RemoveClient(self, object_path):
1437
1401
                "D-Bus method"
1438
 
                for c in tcp_server.clients:
 
1402
                for c in clients:
1439
1403
                    if c.dbus_object_path == object_path:
1440
 
                        tcp_server.clients.remove(c)
 
1404
                        clients.remove(c)
1441
1405
                        c.remove_from_connection()
1442
1406
                        # Don't signal anything except ClientRemoved
1443
1407
                        c.disable(signal=False)
1450
1414
        
1451
1415
        mandos_dbus_service = MandosDBusService()
1452
1416
    
1453
 
    for client in tcp_server.clients:
 
1417
    for client in clients:
1454
1418
        if use_dbus:
1455
1419
            # Emit D-Bus signal
1456
1420
            mandos_dbus_service.ClientAdded(client.dbus_object_path,
1474
1438
    
1475
1439
    try:
1476
1440
        # From the Avahi example code
 
1441
        server.connect_to_signal(u"StateChanged", server_state_changed)
1477
1442
        try:
1478
 
            service.activate()
 
1443
            server_state_changed(server.GetState())
1479
1444
        except dbus.exceptions.DBusException, error:
1480
1445
            logger.critical(u"DBusException: %s", error)
1481
1446
            sys.exit(1)