/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

Merge from trunk; miscellaneous small fixes.  Major points: A lintian
warning (long line in plugin-runner manual page) eliminated as
requested by sponsor, one bug fixed (bashism in mandos-keygen), and
one small inconsistency fixed (server is now started after install).

Show diffs side-by-side

added added

removed removed

Lines of Context:
178
178
class Client(dbus.service.Object):
179
179
    """A representation of a client host served by this server.
180
180
    Attributes:
181
 
    name:       string; from the config file, used in log messages
 
181
    name:       string; from the config file, used in log messages and
 
182
                        D-Bus identifiers
182
183
    fingerprint: string (40 or 32 hexadecimal digits); used to
183
184
                 uniquely identify the client
184
185
    secret:     bytestring; sent verbatim (over TLS) to client
225
226
        if config is None:
226
227
            config = {}
227
228
        logger.debug(u"Creating client %r", self.name)
228
 
        self.use_dbus = use_dbus
229
 
        if self.use_dbus:
230
 
            self.dbus_object_path = (dbus.ObjectPath
231
 
                                     ("/Mandos/clients/"
232
 
                                      + self.name.replace(".", "_")))
233
 
            dbus.service.Object.__init__(self, bus,
234
 
                                         self.dbus_object_path)
 
229
        self.use_dbus = False   # During __init__
235
230
        # Uppercase and remove spaces from fingerprint for later
236
231
        # comparison purposes with return value from the fingerprint()
237
232
        # function
261
256
        self.disable_initiator_tag = None
262
257
        self.checker_callback_tag = None
263
258
        self.checker_command = config["checker"]
 
259
        self.last_connect = None
 
260
        # Only now, when this client is initialized, can it show up on
 
261
        # the D-Bus
 
262
        self.use_dbus = use_dbus
 
263
        if self.use_dbus:
 
264
            self.dbus_object_path = (dbus.ObjectPath
 
265
                                     ("/clients/"
 
266
                                      + self.name.replace(".", "_")))
 
267
            dbus.service.Object.__init__(self, bus,
 
268
                                         self.dbus_object_path)
264
269
    
265
270
    def enable(self):
266
271
        """Start this client's checker and timeout hooks"""
319
324
            # Emit D-Bus signal
320
325
            self.PropertyChanged(dbus.String(u"checker_running"),
321
326
                                 dbus.Boolean(False, variant_level=1))
322
 
        if (os.WIFEXITED(condition)
323
 
            and (os.WEXITSTATUS(condition) == 0)):
324
 
            logger.info(u"Checker for %(name)s succeeded",
325
 
                        vars(self))
 
327
        if os.WIFEXITED(condition):
 
328
            exitstatus = os.WEXITSTATUS(condition)
 
329
            if exitstatus == 0:
 
330
                logger.info(u"Checker for %(name)s succeeded",
 
331
                            vars(self))
 
332
                self.checked_ok()
 
333
            else:
 
334
                logger.info(u"Checker for %(name)s failed",
 
335
                            vars(self))
326
336
            if self.use_dbus:
327
337
                # Emit D-Bus signal
328
 
                self.CheckerCompleted(dbus.Boolean(True),
329
 
                                      dbus.UInt16(condition),
 
338
                self.CheckerCompleted(dbus.Int16(exitstatus),
 
339
                                      dbus.Int64(condition),
330
340
                                      dbus.String(command))
331
 
            self.bump_timeout()
332
 
        elif not os.WIFEXITED(condition):
 
341
        else:
333
342
            logger.warning(u"Checker for %(name)s crashed?",
334
343
                           vars(self))
335
344
            if self.use_dbus:
336
345
                # Emit D-Bus signal
337
 
                self.CheckerCompleted(dbus.Boolean(False),
338
 
                                      dbus.UInt16(condition),
339
 
                                      dbus.String(command))
340
 
        else:
341
 
            logger.info(u"Checker for %(name)s failed",
342
 
                        vars(self))
343
 
            if self.use_dbus:
344
 
                # Emit D-Bus signal
345
 
                self.CheckerCompleted(dbus.Boolean(False),
346
 
                                      dbus.UInt16(condition),
 
346
                self.CheckerCompleted(dbus.Int16(-1),
 
347
                                      dbus.Int64(condition),
347
348
                                      dbus.String(command))
348
349
    
349
 
    def bump_timeout(self):
 
350
    def checked_ok(self):
350
351
        """Bump up the timeout for this client.
351
352
        This should only be called when the client has been seen,
352
353
        alive and well.
448
449
            return now < (self.last_checked_ok + self.timeout)
449
450
    
450
451
    ## D-Bus methods & signals
451
 
    _interface = u"org.mandos_system.Mandos.Client"
 
452
    _interface = u"se.bsnet.fukt.Mandos.Client"
452
453
    
453
 
    # BumpTimeout - method
454
 
    BumpTimeout = dbus.service.method(_interface)(bump_timeout)
455
 
    BumpTimeout.__name__ = "BumpTimeout"
 
454
    # CheckedOK - method
 
455
    CheckedOK = dbus.service.method(_interface)(checked_ok)
 
456
    CheckedOK.__name__ = "CheckedOK"
456
457
    
457
458
    # CheckerCompleted - signal
458
 
    @dbus.service.signal(_interface, signature="bqs")
459
 
    def CheckerCompleted(self, success, condition, command):
 
459
    @dbus.service.signal(_interface, signature="nxs")
 
460
    def CheckerCompleted(self, exitcode, waitstatus, command):
460
461
        "D-Bus signal"
461
462
        pass
462
463
    
503
504
                dbus.String("checker_running"):
504
505
                    dbus.Boolean(self.checker is not None,
505
506
                                 variant_level=1),
 
507
                dbus.String("object_path"):
 
508
                    dbus.ObjectPath(self.dbus_object_path,
 
509
                                    variant_level=1)
506
510
                }, signature="sv")
507
511
    
508
512
    # IsStillValid - method
709
713
            session.bye()
710
714
            return
711
715
        ## This won't work here, since we're in a fork.
712
 
        # client.bump_timeout()
 
716
        # client.checked_ok()
713
717
        sent_size = 0
714
718
        while sent_size < len(client.secret):
715
719
            sent = session.send(client.secret[sent_size:])
1031
1035
                            avahi.DBUS_INTERFACE_SERVER)
1032
1036
    # End of Avahi example code
1033
1037
    if use_dbus:
1034
 
        bus_name = dbus.service.BusName(u"org.mandos-system.Mandos",
1035
 
                                        bus)
 
1038
        bus_name = dbus.service.BusName(u"se.bsnet.fukt.Mandos", bus)
1036
1039
    
1037
1040
    clients.update(Set(Client(name = section,
1038
1041
                              config
1092
1095
        class MandosServer(dbus.service.Object):
1093
1096
            """A D-Bus proxy object"""
1094
1097
            def __init__(self):
1095
 
                dbus.service.Object.__init__(self, bus,
1096
 
                                             "/Mandos")
1097
 
            _interface = u"org.mandos_system.Mandos"
1098
 
 
 
1098
                dbus.service.Object.__init__(self, bus, "/")
 
1099
            _interface = u"se.bsnet.fukt.Mandos"
 
1100
            
1099
1101
            @dbus.service.signal(_interface, signature="oa{sv}")
1100
1102
            def ClientAdded(self, objpath, properties):
1101
1103
                "D-Bus signal"
1102
1104
                pass
1103
 
 
1104
 
            @dbus.service.signal(_interface, signature="o")
1105
 
            def ClientRemoved(self, objpath):
 
1105
            
 
1106
            @dbus.service.signal(_interface, signature="os")
 
1107
            def ClientRemoved(self, objpath, name):
1106
1108
                "D-Bus signal"
1107
1109
                pass
1108
 
 
 
1110
            
1109
1111
            @dbus.service.method(_interface, out_signature="ao")
1110
1112
            def GetAllClients(self):
1111
1113
                return dbus.Array(c.dbus_object_path for c in clients)
1112
 
 
 
1114
            
1113
1115
            @dbus.service.method(_interface, out_signature="a{oa{sv}}")
1114
1116
            def GetAllClientsWithProperties(self):
1115
1117
                return dbus.Dictionary(
1116
1118
                    ((c.dbus_object_path, c.GetAllProperties())
1117
1119
                     for c in clients),
1118
1120
                    signature="oa{sv}")
1119
 
 
 
1121
            
1120
1122
            @dbus.service.method(_interface, in_signature="o")
1121
1123
            def RemoveClient(self, object_path):
1122
1124
                for c in clients:
1126
1128
                        c.use_dbus = False
1127
1129
                        c.disable()
1128
1130
                        # Emit D-Bus signal
1129
 
                        self.ClientRemoved(object_path)
 
1131
                        self.ClientRemoved(object_path, c.name)
1130
1132
                        return
1131
1133
                raise KeyError
1132
 
            @dbus.service.method(_interface)
1133
 
            def Quit(self):
1134
 
                main_loop.quit()
1135
 
 
 
1134
            
1136
1135
            del _interface
1137
 
    
 
1136
        
1138
1137
        mandos_server = MandosServer()
1139
1138
    
1140
1139
    for client in clients: