/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

Show diffs side-by-side

added added

removed removed

Lines of Context:
67
67
from dbus.mainloop.glib import DBusGMainLoop
68
68
import ctypes
69
69
import ctypes.util
70
 
import xml.dom.minidom
71
 
import inspect
72
70
 
73
71
try:
74
72
    SO_BINDTODEVICE = socket.SO_BINDTODEVICE
79
77
        SO_BINDTODEVICE = None
80
78
 
81
79
 
82
 
version = "1.0.13"
 
80
version = "1.0.12"
83
81
 
84
82
logger = logging.Logger(u'mandos')
85
83
syslogger = (logging.handlers.SysLogHandler
249
247
                                    to see if the client lives.
250
248
                                    'None' if no process is running.
251
249
    checker_initiator_tag: a gobject event source tag, or None
252
 
    disable_initiator_tag: - '' -
 
250
    disable_initiator_tag:    - '' -
253
251
    checker_callback_tag:  - '' -
254
252
    checker_command: string; External command which is run to check if
255
253
                     client lives.  %() expansions are done at
259
257
    """
260
258
    
261
259
    @staticmethod
262
 
    def _timedelta_to_milliseconds(td):
263
 
        "Convert a datetime.timedelta() to milliseconds"
264
 
        return ((td.days * 24 * 60 * 60 * 1000)
265
 
                + (td.seconds * 1000)
266
 
                + (td.microseconds // 1000))
 
260
    def _datetime_to_milliseconds(dt):
 
261
        "Convert a datetime.datetime() to milliseconds"
 
262
        return ((dt.days * 24 * 60 * 60 * 1000)
 
263
                + (dt.seconds * 1000)
 
264
                + (dt.microseconds // 1000))
267
265
    
268
266
    def timeout_milliseconds(self):
269
267
        "Return the 'timeout' attribute in milliseconds"
270
 
        return self._timedelta_to_milliseconds(self.timeout)
 
268
        return self._datetime_to_milliseconds(self.timeout)
271
269
    
272
270
    def interval_milliseconds(self):
273
271
        "Return the 'interval' attribute in milliseconds"
274
 
        return self._timedelta_to_milliseconds(self.interval)
 
272
        return self._datetime_to_milliseconds(self.interval)
275
273
    
276
274
    def __init__(self, name = None, disable_hook=None, config=None):
277
275
        """Note: the 'checker' key in 'config' sets the
292
290
        elif u"secfile" in config:
293
291
            with closing(open(os.path.expanduser
294
292
                              (os.path.expandvars
295
 
                               (config[u"secfile"])),
296
 
                              "rb")) as secfile:
 
293
                               (config[u"secfile"])))) as secfile:
297
294
                self.secret = secfile.read()
298
295
        else:
299
296
            raise TypeError(u"No secret or secfile for client %s"
399
396
        # is as it should be.
400
397
        
401
398
        # If a checker exists, make sure it is not a zombie
402
 
        try:
 
399
        if self.checker is not None:
403
400
            pid, status = os.waitpid(self.checker.pid, os.WNOHANG)
404
 
        except (AttributeError, OSError), error:
405
 
            if (isinstance(error, OSError)
406
 
                and error.errno != errno.ECHILD):
407
 
                raise error
408
 
        else:
409
401
            if pid:
410
402
                logger.warning(u"Checker was a zombie")
411
403
                gobject.source_remove(self.checker_callback_tag)
486
478
            return now < (self.last_checked_ok + self.timeout)
487
479
 
488
480
 
489
 
def dbus_service_property(dbus_interface, signature=u"v",
490
 
                          access=u"readwrite", byte_arrays=False):
491
 
    """Decorators for marking methods of a DBusObjectWithProperties to
492
 
    become properties on the D-Bus.
493
 
    
494
 
    The decorated method will be called with no arguments by "Get"
495
 
    and with one argument by "Set".
496
 
    
497
 
    The parameters, where they are supported, are the same as
498
 
    dbus.service.method, except there is only "signature", since the
499
 
    type from Get() and the type sent to Set() is the same.
500
 
    """
501
 
    def decorator(func):
502
 
        func._dbus_is_property = True
503
 
        func._dbus_interface = dbus_interface
504
 
        func._dbus_signature = signature
505
 
        func._dbus_access = access
506
 
        func._dbus_name = func.__name__
507
 
        if func._dbus_name.endswith(u"_dbus_property"):
508
 
            func._dbus_name = func._dbus_name[:-14]
509
 
        func._dbus_get_args_options = {u'byte_arrays': byte_arrays }
510
 
        return func
511
 
    return decorator
512
 
 
513
 
 
514
 
class DBusPropertyException(dbus.exceptions.DBusException):
515
 
    """A base class for D-Bus property-related exceptions
516
 
    """
517
 
    def __unicode__(self):
518
 
        return unicode(str(self))
519
 
 
520
 
 
521
 
class DBusPropertyAccessException(DBusPropertyException):
522
 
    """A property's access permissions disallows an operation.
523
 
    """
524
 
    pass
525
 
 
526
 
 
527
 
class DBusPropertyNotFound(DBusPropertyException):
528
 
    """An attempt was made to access a non-existing property.
529
 
    """
530
 
    pass
531
 
 
532
 
 
533
 
class DBusObjectWithProperties(dbus.service.Object):
534
 
    """A D-Bus object with properties.
535
 
 
536
 
    Classes inheriting from this can use the dbus_service_property
537
 
    decorator to expose methods as D-Bus properties.  It exposes the
538
 
    standard Get(), Set(), and GetAll() methods on the D-Bus.
539
 
    """
540
 
    
541
 
    @staticmethod
542
 
    def _is_dbus_property(obj):
543
 
        return getattr(obj, u"_dbus_is_property", False)
544
 
    
545
 
    def _get_all_dbus_properties(self):
546
 
        """Returns a generator of (name, attribute) pairs
547
 
        """
548
 
        return ((prop._dbus_name, prop)
549
 
                for name, prop in
550
 
                inspect.getmembers(self, self._is_dbus_property))
551
 
    
552
 
    def _get_dbus_property(self, interface_name, property_name):
553
 
        """Returns a bound method if one exists which is a D-Bus
554
 
        property with the specified name and interface.
555
 
        """
556
 
        for name in (property_name,
557
 
                     property_name + u"_dbus_property"):
558
 
            prop = getattr(self, name, None)
559
 
            if (prop is None
560
 
                or not self._is_dbus_property(prop)
561
 
                or prop._dbus_name != property_name
562
 
                or (interface_name and prop._dbus_interface
563
 
                    and interface_name != prop._dbus_interface)):
564
 
                continue
565
 
            return prop
566
 
        # No such property
567
 
        raise DBusPropertyNotFound(self.dbus_object_path + u":"
568
 
                                   + interface_name + u"."
569
 
                                   + property_name)
570
 
    
571
 
    @dbus.service.method(dbus.PROPERTIES_IFACE, in_signature=u"ss",
572
 
                         out_signature=u"v")
573
 
    def Get(self, interface_name, property_name):
574
 
        """Standard D-Bus property Get() method, see D-Bus standard.
575
 
        """
576
 
        prop = self._get_dbus_property(interface_name, property_name)
577
 
        if prop._dbus_access == u"write":
578
 
            raise DBusPropertyAccessException(property_name)
579
 
        value = prop()
580
 
        if not hasattr(value, u"variant_level"):
581
 
            return value
582
 
        return type(value)(value, variant_level=value.variant_level+1)
583
 
    
584
 
    @dbus.service.method(dbus.PROPERTIES_IFACE, in_signature=u"ssv")
585
 
    def Set(self, interface_name, property_name, value):
586
 
        """Standard D-Bus property Set() method, see D-Bus standard.
587
 
        """
588
 
        prop = self._get_dbus_property(interface_name, property_name)
589
 
        if prop._dbus_access == u"read":
590
 
            raise DBusPropertyAccessException(property_name)
591
 
        if prop._dbus_get_args_options[u"byte_arrays"]:
592
 
            value = dbus.ByteArray(''.join(unichr(byte)
593
 
                                           for byte in value))
594
 
        prop(value)
595
 
    
596
 
    @dbus.service.method(dbus.PROPERTIES_IFACE, in_signature=u"s",
597
 
                         out_signature=u"a{sv}")
598
 
    def GetAll(self, interface_name):
599
 
        """Standard D-Bus property GetAll() method, see D-Bus
600
 
        standard.
601
 
 
602
 
        Note: Will not include properties with access="write".
603
 
        """
604
 
        all = {}
605
 
        for name, prop in self._get_all_dbus_properties():
606
 
            if (interface_name
607
 
                and interface_name != prop._dbus_interface):
608
 
                # Interface non-empty but did not match
609
 
                continue
610
 
            # Ignore write-only properties
611
 
            if prop._dbus_access == u"write":
612
 
                continue
613
 
            value = prop()
614
 
            if not hasattr(value, u"variant_level"):
615
 
                all[name] = value
616
 
                continue
617
 
            all[name] = type(value)(value, variant_level=
618
 
                                    value.variant_level+1)
619
 
        return dbus.Dictionary(all, signature=u"sv")
620
 
    
621
 
    @dbus.service.method(dbus.INTROSPECTABLE_IFACE,
622
 
                         out_signature=u"s",
623
 
                         path_keyword='object_path',
624
 
                         connection_keyword='connection')
625
 
    def Introspect(self, object_path, connection):
626
 
        """Standard D-Bus method, overloaded to insert property tags.
627
 
        """
628
 
        xmlstring = dbus.service.Object.Introspect(self, object_path,
629
 
                                                   connection)
630
 
        try:
631
 
            document = xml.dom.minidom.parseString(xmlstring)
632
 
            def make_tag(document, name, prop):
633
 
                e = document.createElement(u"property")
634
 
                e.setAttribute(u"name", name)
635
 
                e.setAttribute(u"type", prop._dbus_signature)
636
 
                e.setAttribute(u"access", prop._dbus_access)
637
 
                return e
638
 
            for if_tag in document.getElementsByTagName(u"interface"):
639
 
                for tag in (make_tag(document, name, prop)
640
 
                            for name, prop
641
 
                            in self._get_all_dbus_properties()
642
 
                            if prop._dbus_interface
643
 
                            == if_tag.getAttribute(u"name")):
644
 
                    if_tag.appendChild(tag)
645
 
                # Add the names to the return values for the
646
 
                # "org.freedesktop.DBus.Properties" methods
647
 
                if (if_tag.getAttribute(u"name")
648
 
                    == u"org.freedesktop.DBus.Properties"):
649
 
                    for cn in if_tag.getElementsByTagName(u"method"):
650
 
                        if cn.getAttribute(u"name") == u"Get":
651
 
                            for arg in cn.getElementsByTagName(u"arg"):
652
 
                                if (arg.getAttribute(u"direction")
653
 
                                    == u"out"):
654
 
                                    arg.setAttribute(u"name", u"value")
655
 
                        elif cn.getAttribute(u"name") == u"GetAll":
656
 
                            for arg in cn.getElementsByTagName(u"arg"):
657
 
                                if (arg.getAttribute(u"direction")
658
 
                                    == u"out"):
659
 
                                    arg.setAttribute(u"name", u"props")
660
 
            xmlstring = document.toxml(u"utf-8")
661
 
            document.unlink()
662
 
        except (AttributeError, xml.dom.DOMException,
663
 
                xml.parsers.expat.ExpatError), error:
664
 
            logger.error(u"Failed to override Introspection method",
665
 
                         error)
666
 
        return xmlstring
667
 
 
668
 
 
669
 
class ClientDBus(Client, DBusObjectWithProperties):
 
481
class ClientDBus(Client, dbus.service.Object):
670
482
    """A Client class using D-Bus
671
483
    
672
484
    Attributes:
683
495
        self.dbus_object_path = (dbus.ObjectPath
684
496
                                 (u"/clients/"
685
497
                                  + self.name.replace(u".", u"_")))
686
 
        DBusObjectWithProperties.__init__(self, self.bus,
687
 
                                          self.dbus_object_path)
 
498
        dbus.service.Object.__init__(self, self.bus,
 
499
                                     self.dbus_object_path)
688
500
    
689
501
    @staticmethod
690
502
    def _datetime_to_dbus(dt, variant_level=0):
719
531
            self.remove_from_connection()
720
532
        except LookupError:
721
533
            pass
722
 
        if hasattr(DBusObjectWithProperties, u"__del__"):
723
 
            DBusObjectWithProperties.__del__(self, *args, **kwargs)
 
534
        if hasattr(dbus.service.Object, u"__del__"):
 
535
            dbus.service.Object.__del__(self, *args, **kwargs)
724
536
        Client.__del__(self, *args, **kwargs)
725
537
    
726
538
    def checker_callback(self, pid, condition, command,
800
612
        "D-Bus signal"
801
613
        pass
802
614
    
 
615
    # GetAllProperties - method
 
616
    @dbus.service.method(_interface, out_signature=u"a{sv}")
 
617
    def GetAllProperties(self):
 
618
        "D-Bus method"
 
619
        return dbus.Dictionary({
 
620
                dbus.String(u"name"):
 
621
                    dbus.String(self.name, variant_level=1),
 
622
                dbus.String(u"fingerprint"):
 
623
                    dbus.String(self.fingerprint, variant_level=1),
 
624
                dbus.String(u"host"):
 
625
                    dbus.String(self.host, variant_level=1),
 
626
                dbus.String(u"created"):
 
627
                    self._datetime_to_dbus(self.created,
 
628
                                           variant_level=1),
 
629
                dbus.String(u"last_enabled"):
 
630
                    (self._datetime_to_dbus(self.last_enabled,
 
631
                                            variant_level=1)
 
632
                     if self.last_enabled is not None
 
633
                     else dbus.Boolean(False, variant_level=1)),
 
634
                dbus.String(u"enabled"):
 
635
                    dbus.Boolean(self.enabled, variant_level=1),
 
636
                dbus.String(u"last_checked_ok"):
 
637
                    (self._datetime_to_dbus(self.last_checked_ok,
 
638
                                            variant_level=1)
 
639
                     if self.last_checked_ok is not None
 
640
                     else dbus.Boolean (False, variant_level=1)),
 
641
                dbus.String(u"timeout"):
 
642
                    dbus.UInt64(self.timeout_milliseconds(),
 
643
                                variant_level=1),
 
644
                dbus.String(u"interval"):
 
645
                    dbus.UInt64(self.interval_milliseconds(),
 
646
                                variant_level=1),
 
647
                dbus.String(u"checker"):
 
648
                    dbus.String(self.checker_command,
 
649
                                variant_level=1),
 
650
                dbus.String(u"checker_running"):
 
651
                    dbus.Boolean(self.checker is not None,
 
652
                                 variant_level=1),
 
653
                dbus.String(u"object_path"):
 
654
                    dbus.ObjectPath(self.dbus_object_path,
 
655
                                    variant_level=1)
 
656
                }, signature=u"sv")
 
657
    
 
658
    # IsStillValid - method
 
659
    @dbus.service.method(_interface, out_signature=u"b")
 
660
    def IsStillValid(self):
 
661
        return self.still_valid()
 
662
    
803
663
    # PropertyChanged - signal
804
664
    @dbus.service.signal(_interface, signature=u"sv")
805
665
    def PropertyChanged(self, property, value):
806
666
        "D-Bus signal"
807
667
        pass
808
668
    
809
 
    # GotSecret - signal
 
669
    # ReceivedSecret - signal
810
670
    @dbus.service.signal(_interface)
811
 
    def GotSecret(self):
 
671
    def ReceivedSecret(self):
812
672
        "D-Bus signal"
813
673
        pass
814
674
    
818
678
        "D-Bus signal"
819
679
        pass
820
680
    
 
681
    # SetChecker - method
 
682
    @dbus.service.method(_interface, in_signature=u"s")
 
683
    def SetChecker(self, checker):
 
684
        "D-Bus setter method"
 
685
        self.checker_command = checker
 
686
        # Emit D-Bus signal
 
687
        self.PropertyChanged(dbus.String(u"checker"),
 
688
                             dbus.String(self.checker_command,
 
689
                                         variant_level=1))
 
690
    
 
691
    # SetHost - method
 
692
    @dbus.service.method(_interface, in_signature=u"s")
 
693
    def SetHost(self, host):
 
694
        "D-Bus setter method"
 
695
        self.host = host
 
696
        # Emit D-Bus signal
 
697
        self.PropertyChanged(dbus.String(u"host"),
 
698
                             dbus.String(self.host, variant_level=1))
 
699
    
 
700
    # SetInterval - method
 
701
    @dbus.service.method(_interface, in_signature=u"t")
 
702
    def SetInterval(self, milliseconds):
 
703
        self.interval = datetime.timedelta(0, 0, 0, milliseconds)
 
704
        # Emit D-Bus signal
 
705
        self.PropertyChanged(dbus.String(u"interval"),
 
706
                             (dbus.UInt64(self
 
707
                                          .interval_milliseconds(),
 
708
                                          variant_level=1)))
 
709
    
 
710
    # SetSecret - method
 
711
    @dbus.service.method(_interface, in_signature=u"ay",
 
712
                         byte_arrays=True)
 
713
    def SetSecret(self, secret):
 
714
        "D-Bus setter method"
 
715
        self.secret = str(secret)
 
716
    
 
717
    # SetTimeout - method
 
718
    @dbus.service.method(_interface, in_signature=u"t")
 
719
    def SetTimeout(self, milliseconds):
 
720
        self.timeout = datetime.timedelta(0, 0, 0, milliseconds)
 
721
        # Emit D-Bus signal
 
722
        self.PropertyChanged(dbus.String(u"timeout"),
 
723
                             (dbus.UInt64(self.timeout_milliseconds(),
 
724
                                          variant_level=1)))
 
725
    
821
726
    # Enable - method
822
727
    @dbus.service.method(_interface)
823
728
    def Enable(self):
841
746
    def StopChecker(self):
842
747
        self.stop_checker()
843
748
    
844
 
    # name - property
845
 
    @dbus_service_property(_interface, signature=u"s", access=u"read")
846
 
    def name_dbus_property(self):
847
 
        return dbus.String(self.name)
848
 
    
849
 
    # fingerprint - property
850
 
    @dbus_service_property(_interface, signature=u"s", access=u"read")
851
 
    def fingerprint_dbus_property(self):
852
 
        return dbus.String(self.fingerprint)
853
 
    
854
 
    # host - property
855
 
    @dbus_service_property(_interface, signature=u"s",
856
 
                           access=u"readwrite")
857
 
    def host_dbus_property(self, value=None):
858
 
        if value is None:       # get
859
 
            return dbus.String(self.host)
860
 
        self.host = value
861
 
        # Emit D-Bus signal
862
 
        self.PropertyChanged(dbus.String(u"host"),
863
 
                             dbus.String(value, variant_level=1))
864
 
    
865
 
    # created - property
866
 
    @dbus_service_property(_interface, signature=u"s", access=u"read")
867
 
    def created_dbus_property(self):
868
 
        return dbus.String(self._datetime_to_dbus(self.created))
869
 
    
870
 
    # last_enabled - property
871
 
    @dbus_service_property(_interface, signature=u"s", access=u"read")
872
 
    def last_enabled_dbus_property(self):
873
 
        if self.last_enabled is None:
874
 
            return dbus.String(u"")
875
 
        return dbus.String(self._datetime_to_dbus(self.last_enabled))
876
 
    
877
 
    # enabled - property
878
 
    @dbus_service_property(_interface, signature=u"b",
879
 
                           access=u"readwrite")
880
 
    def enabled_dbus_property(self, value=None):
881
 
        if value is None:       # get
882
 
            return dbus.Boolean(self.enabled)
883
 
        if value:
884
 
            self.enable()
885
 
        else:
886
 
            self.disable()
887
 
    
888
 
    # last_checked_ok - property
889
 
    @dbus_service_property(_interface, signature=u"s",
890
 
                           access=u"readwrite")
891
 
    def last_checked_ok_dbus_property(self, value=None):
892
 
        if value is not None:
893
 
            self.checked_ok()
894
 
            return
895
 
        if self.last_checked_ok is None:
896
 
            return dbus.String(u"")
897
 
        return dbus.String(self._datetime_to_dbus(self
898
 
                                                  .last_checked_ok))
899
 
    
900
 
    # timeout - property
901
 
    @dbus_service_property(_interface, signature=u"t",
902
 
                           access=u"readwrite")
903
 
    def timeout_dbus_property(self, value=None):
904
 
        if value is None:       # get
905
 
            return dbus.UInt64(self.timeout_milliseconds())
906
 
        self.timeout = datetime.timedelta(0, 0, 0, value)
907
 
        # Emit D-Bus signal
908
 
        self.PropertyChanged(dbus.String(u"timeout"),
909
 
                             dbus.UInt64(value, variant_level=1))
910
 
        if getattr(self, u"disable_initiator_tag", None) is None:
911
 
            return
912
 
        # Reschedule timeout
913
 
        gobject.source_remove(self.disable_initiator_tag)
914
 
        self.disable_initiator_tag = None
915
 
        time_to_die = (self.
916
 
                       _timedelta_to_milliseconds((self
917
 
                                                   .last_checked_ok
918
 
                                                   + self.timeout)
919
 
                                                  - datetime.datetime
920
 
                                                  .utcnow()))
921
 
        if time_to_die <= 0:
922
 
            # The timeout has passed
923
 
            self.disable()
924
 
        else:
925
 
            self.disable_initiator_tag = (gobject.timeout_add
926
 
                                          (time_to_die, self.disable))
927
 
    
928
 
    # interval - property
929
 
    @dbus_service_property(_interface, signature=u"t",
930
 
                           access=u"readwrite")
931
 
    def interval_dbus_property(self, value=None):
932
 
        if value is None:       # get
933
 
            return dbus.UInt64(self.interval_milliseconds())
934
 
        self.interval = datetime.timedelta(0, 0, 0, value)
935
 
        # Emit D-Bus signal
936
 
        self.PropertyChanged(dbus.String(u"interval"),
937
 
                             dbus.UInt64(value, variant_level=1))
938
 
        if getattr(self, u"checker_initiator_tag", None) is None:
939
 
            return
940
 
        # Reschedule checker run
941
 
        gobject.source_remove(self.checker_initiator_tag)
942
 
        self.checker_initiator_tag = (gobject.timeout_add
943
 
                                      (value, self.start_checker))
944
 
        self.start_checker()    # Start one now, too
945
 
 
946
 
    # checker - property
947
 
    @dbus_service_property(_interface, signature=u"s",
948
 
                           access=u"readwrite")
949
 
    def checker_dbus_property(self, value=None):
950
 
        if value is None:       # get
951
 
            return dbus.String(self.checker_command)
952
 
        self.checker_command = value
953
 
        # Emit D-Bus signal
954
 
        self.PropertyChanged(dbus.String(u"checker"),
955
 
                             dbus.String(self.checker_command,
956
 
                                         variant_level=1))
957
 
    
958
 
    # checker_running - property
959
 
    @dbus_service_property(_interface, signature=u"b",
960
 
                           access=u"readwrite")
961
 
    def checker_running_dbus_property(self, value=None):
962
 
        if value is None:       # get
963
 
            return dbus.Boolean(self.checker is not None)
964
 
        if value:
965
 
            self.start_checker()
966
 
        else:
967
 
            self.stop_checker()
968
 
    
969
 
    # object_path - property
970
 
    @dbus_service_property(_interface, signature=u"o", access=u"read")
971
 
    def object_path_dbus_property(self):
972
 
        return self.dbus_object_path # is already a dbus.ObjectPath
973
 
    
974
 
    # secret = property
975
 
    @dbus_service_property(_interface, signature=u"ay",
976
 
                           access=u"write", byte_arrays=True)
977
 
    def secret_dbus_property(self, value):
978
 
        self.secret = str(value)
979
 
    
980
749
    del _interface
981
750
 
982
751
 
1301
1070
                    client.checked_ok()
1302
1071
                    if self.use_dbus:
1303
1072
                        # Emit D-Bus signal
1304
 
                        client.GotSecret()
 
1073
                        client.ReceivedSecret()
1305
1074
                    break
1306
1075
            else:
1307
1076
                logger.error(u"Sending secret to unknown client %s",
1392
1161
        null = os.open(os.path.devnull, os.O_NOCTTY | os.O_RDWR)
1393
1162
        if not stat.S_ISCHR(os.fstat(null).st_mode):
1394
1163
            raise OSError(errno.ENODEV,
1395
 
                          u"%s not a character device"
1396
 
                          % os.path.devnull)
 
1164
                          u"/dev/null not a character device")
1397
1165
        os.dup2(null, sys.stdin.fileno())
1398
1166
        os.dup2(null, sys.stdout.fileno())
1399
1167
        os.dup2(null, sys.stderr.fileno())
1659
1427
            def GetAllClientsWithProperties(self):
1660
1428
                "D-Bus method"
1661
1429
                return dbus.Dictionary(
1662
 
                    ((c.dbus_object_path, c.GetAll(u""))
 
1430
                    ((c.dbus_object_path, c.GetAllProperties())
1663
1431
                     for c in tcp_server.clients),
1664
1432
                    signature=u"oa{sv}")
1665
1433
            
1685
1453
        if use_dbus:
1686
1454
            # Emit D-Bus signal
1687
1455
            mandos_dbus_service.ClientAdded(client.dbus_object_path,
1688
 
                                            client.GetAll(u""))
 
1456
                                            client.GetAllProperties())
1689
1457
        client.enable()
1690
1458
    
1691
1459
    tcp_server.enable()