/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: 2015-07-07 15:49:49 UTC
  • Revision ID: teddy@recompile.se-20150707154949-vbuj4pc6wf3o1vgz
mandos.service: Use Type=dbus (implicitly).

mandos.service ([Service]/Type): Removed.
               ([Service]/BusName): Uncommented; set to
                                    "se.recompile.Mandos".

Show diffs side-by-side

added added

removed removed

Lines of Context:
395
395
                    logger.error(bad_states[state] + ": %r", error)
396
396
            self.cleanup()
397
397
        elif state == avahi.SERVER_RUNNING:
398
 
            try:
399
 
                self.add()
400
 
            except dbus.exceptions.DBusException as error:
401
 
                if (error.get_dbus_name()
402
 
                    == "org.freedesktop.Avahi.CollisionError"):
403
 
                    logger.info("Local Zeroconf service name"
404
 
                                " collision.")
405
 
                    return self.rename(remove=False)
406
 
                else:
407
 
                    logger.critical("D-Bus Exception", exc_info=error)
408
 
                    self.cleanup()
409
 
                    os._exit(1)
 
398
            self.add()
410
399
        else:
411
400
            if error is None:
412
401
                logger.debug("Unknown state: %r", state)
842
831
                           access="r")
843
832
    def Property_dbus_property(self):
844
833
        return dbus.Boolean(False)
845
 
    
846
 
    See also the DBusObjectWithAnnotations class.
847
834
    """
848
835
    
849
836
    def decorator(func):
871
858
    pass
872
859
 
873
860
 
874
 
class DBusObjectWithAnnotations(dbus.service.Object):
875
 
    """A D-Bus object with annotations.
 
861
class DBusObjectWithProperties(dbus.service.Object):
 
862
    """A D-Bus object with properties.
876
863
    
877
 
    Classes inheriting from this can use the dbus_annotations
878
 
    decorator to add annotations to methods or signals.
 
864
    Classes inheriting from this can use the dbus_service_property
 
865
    decorator to expose methods as D-Bus properties.  It exposes the
 
866
    standard Get(), Set(), and GetAll() methods on the D-Bus.
879
867
    """
880
868
    
881
869
    @staticmethod
897
885
                for name, athing in
898
886
                inspect.getmembers(cls, self._is_dbus_thing(thing)))
899
887
    
900
 
    @dbus.service.method(dbus.INTROSPECTABLE_IFACE,
901
 
                         out_signature = "s",
902
 
                         path_keyword = 'object_path',
903
 
                         connection_keyword = 'connection')
904
 
    def Introspect(self, object_path, connection):
905
 
        """Overloading of standard D-Bus method.
906
 
        
907
 
        Inserts annotation tags on methods and signals.
908
 
        """
909
 
        xmlstring = dbus.service.Object.Introspect(self, object_path,
910
 
                                                   connection)
911
 
        try:
912
 
            document = xml.dom.minidom.parseString(xmlstring)
913
 
            
914
 
            for if_tag in document.getElementsByTagName("interface"):
915
 
                # Add annotation tags
916
 
                for typ in ("method", "signal"):
917
 
                    for tag in if_tag.getElementsByTagName(typ):
918
 
                        annots = dict()
919
 
                        for name, prop in (self.
920
 
                                           _get_all_dbus_things(typ)):
921
 
                            if (name == tag.getAttribute("name")
922
 
                                and prop._dbus_interface
923
 
                                == if_tag.getAttribute("name")):
924
 
                                annots.update(getattr(
925
 
                                    prop, "_dbus_annotations", {}))
926
 
                        for name, value in annots.items():
927
 
                            ann_tag = document.createElement(
928
 
                                "annotation")
929
 
                            ann_tag.setAttribute("name", name)
930
 
                            ann_tag.setAttribute("value", value)
931
 
                            tag.appendChild(ann_tag)
932
 
                # Add interface annotation tags
933
 
                for annotation, value in dict(
934
 
                    itertools.chain.from_iterable(
935
 
                        annotations().items()
936
 
                        for name, annotations
937
 
                        in self._get_all_dbus_things("interface")
938
 
                        if name == if_tag.getAttribute("name")
939
 
                        )).items():
940
 
                    ann_tag = document.createElement("annotation")
941
 
                    ann_tag.setAttribute("name", annotation)
942
 
                    ann_tag.setAttribute("value", value)
943
 
                    if_tag.appendChild(ann_tag)
944
 
                # Fix argument name for the Introspect method itself
945
 
                if (if_tag.getAttribute("name")
946
 
                                == dbus.INTROSPECTABLE_IFACE):
947
 
                    for cn in if_tag.getElementsByTagName("method"):
948
 
                        if cn.getAttribute("name") == "Introspect":
949
 
                            for arg in cn.getElementsByTagName("arg"):
950
 
                                if (arg.getAttribute("direction")
951
 
                                    == "out"):
952
 
                                    arg.setAttribute("name",
953
 
                                                     "xml_data")
954
 
            xmlstring = document.toxml("utf-8")
955
 
            document.unlink()
956
 
        except (AttributeError, xml.dom.DOMException,
957
 
                xml.parsers.expat.ExpatError) as error:
958
 
            logger.error("Failed to override Introspection method",
959
 
                         exc_info=error)
960
 
        return xmlstring
961
 
 
962
 
 
963
 
class DBusObjectWithProperties(DBusObjectWithAnnotations):
964
 
    """A D-Bus object with properties.
965
 
    
966
 
    Classes inheriting from this can use the dbus_service_property
967
 
    decorator to expose methods as D-Bus properties.  It exposes the
968
 
    standard Get(), Set(), and GetAll() methods on the D-Bus.
969
 
    """
970
 
    
971
888
    def _get_dbus_property(self, interface_name, property_name):
972
889
        """Returns a bound method if one exists which is a D-Bus
973
890
        property with the specified name and interface.
1058
975
        
1059
976
        Inserts property tags and interface annotation tags.
1060
977
        """
1061
 
        xmlstring = DBusObjectWithAnnotations.Introspect(self,
1062
 
                                                         object_path,
1063
 
                                                         connection)
 
978
        xmlstring = dbus.service.Object.Introspect(self, object_path,
 
979
                                                   connection)
1064
980
        try:
1065
981
            document = xml.dom.minidom.parseString(xmlstring)
1066
982
            
1079
995
                            if prop._dbus_interface
1080
996
                            == if_tag.getAttribute("name")):
1081
997
                    if_tag.appendChild(tag)
1082
 
                # Add annotation tags for properties
1083
 
                for tag in if_tag.getElementsByTagName("property"):
1084
 
                    annots = dict()
1085
 
                    for name, prop in self._get_all_dbus_things(
1086
 
                            "property"):
1087
 
                        if (name == tag.getAttribute("name")
1088
 
                            and prop._dbus_interface
1089
 
                            == if_tag.getAttribute("name")):
1090
 
                            annots.update(getattr(
1091
 
                                prop, "_dbus_annotations", {}))
1092
 
                    for name, value in annots.items():
1093
 
                        ann_tag = document.createElement(
1094
 
                            "annotation")
1095
 
                        ann_tag.setAttribute("name", name)
1096
 
                        ann_tag.setAttribute("value", value)
1097
 
                        tag.appendChild(ann_tag)
 
998
                # Add annotation tags
 
999
                for typ in ("method", "signal", "property"):
 
1000
                    for tag in if_tag.getElementsByTagName(typ):
 
1001
                        annots = dict()
 
1002
                        for name, prop in (self.
 
1003
                                           _get_all_dbus_things(typ)):
 
1004
                            if (name == tag.getAttribute("name")
 
1005
                                and prop._dbus_interface
 
1006
                                == if_tag.getAttribute("name")):
 
1007
                                annots.update(getattr(
 
1008
                                    prop, "_dbus_annotations", {}))
 
1009
                        for name, value in annots.items():
 
1010
                            ann_tag = document.createElement(
 
1011
                                "annotation")
 
1012
                            ann_tag.setAttribute("name", name)
 
1013
                            ann_tag.setAttribute("value", value)
 
1014
                            tag.appendChild(ann_tag)
 
1015
                # Add interface annotation tags
 
1016
                for annotation, value in dict(
 
1017
                    itertools.chain.from_iterable(
 
1018
                        annotations().items()
 
1019
                        for name, annotations
 
1020
                        in self._get_all_dbus_things("interface")
 
1021
                        if name == if_tag.getAttribute("name")
 
1022
                        )).items():
 
1023
                    ann_tag = document.createElement("annotation")
 
1024
                    ann_tag.setAttribute("name", annotation)
 
1025
                    ann_tag.setAttribute("value", value)
 
1026
                    if_tag.appendChild(ann_tag)
1098
1027
                # Add the names to the return values for the
1099
1028
                # "org.freedesktop.DBus.Properties" methods
1100
1029
                if (if_tag.getAttribute("name")
1436
1365
        if exitstatus >= 0:
1437
1366
            # Emit D-Bus signal
1438
1367
            self.CheckerCompleted(dbus.Int16(exitstatus),
1439
 
                                  # This is specific to GNU libC
1440
 
                                  dbus.Int64(exitstatus << 8),
 
1368
                                  dbus.Int64(0),
1441
1369
                                  dbus.String(command))
1442
1370
        else:
1443
1371
            # Emit D-Bus signal
1444
1372
            self.CheckerCompleted(dbus.Int16(-1),
1445
1373
                                  dbus.Int64(
1446
 
                                      # This is specific to GNU libC
1447
 
                                      (exitstatus << 8)
1448
 
                                      | self.last_checker_signal),
 
1374
                                      self.last_checker_signal),
1449
1375
                                  dbus.String(command))
1450
1376
        return ret
1451
1377
    
1528
1454
        self.checked_ok()
1529
1455
    
1530
1456
    # Enable - method
1531
 
    @dbus_annotations({"org.freedesktop.DBus.Deprecated": "true"})
1532
1457
    @dbus.service.method(_interface)
1533
1458
    def Enable(self):
1534
1459
        "D-Bus method"
1535
1460
        self.enable()
1536
1461
    
1537
1462
    # StartChecker - method
1538
 
    @dbus_annotations({"org.freedesktop.DBus.Deprecated": "true"})
1539
1463
    @dbus.service.method(_interface)
1540
1464
    def StartChecker(self):
1541
1465
        "D-Bus method"
1542
1466
        self.start_checker()
1543
1467
    
1544
1468
    # Disable - method
1545
 
    @dbus_annotations({"org.freedesktop.DBus.Deprecated": "true"})
1546
1469
    @dbus.service.method(_interface)
1547
1470
    def Disable(self):
1548
1471
        "D-Bus method"
1549
1472
        self.disable()
1550
1473
    
1551
1474
    # StopChecker - method
1552
 
    @dbus_annotations({"org.freedesktop.DBus.Deprecated": "true"})
1553
1475
    @dbus.service.method(_interface)
1554
1476
    def StopChecker(self):
1555
1477
        self.stop_checker()
1591
1513
        self.approval_duration = datetime.timedelta(0, 0, 0, value)
1592
1514
    
1593
1515
    # Name - property
1594
 
    @dbus_annotations(
1595
 
        {"org.freedesktop.DBus.Property.EmitsChangedSignal": "const"})
1596
1516
    @dbus_service_property(_interface, signature="s", access="read")
1597
1517
    def Name_dbus_property(self):
1598
1518
        return dbus.String(self.name)
1599
1519
    
1600
1520
    # Fingerprint - property
1601
 
    @dbus_annotations(
1602
 
        {"org.freedesktop.DBus.Property.EmitsChangedSignal": "const"})
1603
1521
    @dbus_service_property(_interface, signature="s", access="read")
1604
1522
    def Fingerprint_dbus_property(self):
1605
1523
        return dbus.String(self.fingerprint)
1614
1532
        self.host = str(value)
1615
1533
    
1616
1534
    # Created - property
1617
 
    @dbus_annotations(
1618
 
        {"org.freedesktop.DBus.Property.EmitsChangedSignal": "const"})
1619
1535
    @dbus_service_property(_interface, signature="s", access="read")
1620
1536
    def Created_dbus_property(self):
1621
1537
        return datetime_to_dbus(self.created)
1736
1652
            self.stop_checker()
1737
1653
    
1738
1654
    # ObjectPath - property
1739
 
    @dbus_annotations(
1740
 
        {"org.freedesktop.DBus.Property.EmitsChangedSignal": "const",
1741
 
         "org.freedesktop.DBus.Deprecated": "true"})
1742
1655
    @dbus_service_property(_interface, signature="o", access="read")
1743
1656
    def ObjectPath_dbus_property(self):
1744
1657
        return self.dbus_object_path # is already a dbus.ObjectPath
1745
1658
    
1746
1659
    # Secret = property
1747
 
    @dbus_annotations(
1748
 
        {"org.freedesktop.DBus.Property.EmitsChangedSignal":
1749
 
         "invalidates"})
1750
1660
    @dbus_service_property(_interface,
1751
1661
                           signature="ay",
1752
1662
                           access="write",
2476
2386
                        "debug": "False",
2477
2387
                        "priority":
2478
2388
                        "SECURE256:!CTYPE-X.509:+CTYPE-OPENPGP:!RSA"
2479
 
                        ":+SIGN-DSA-SHA256",
 
2389
                        ":+SIGN-RSA-SHA224:+SIGN-RSA-RMD160",
2480
2390
                        "servicename": "Mandos",
2481
2391
                        "use_dbus": "True",
2482
2392
                        "use_ipv6": "True",
2813
2723
        
2814
2724
        @alternate_dbus_interfaces(
2815
2725
            { "se.recompile.Mandos": "se.bsnet.fukt.Mandos" })
2816
 
        class MandosDBusService(DBusObjectWithAnnotations):
 
2726
        class MandosDBusService(DBusObjectWithProperties):
2817
2727
            """A D-Bus proxy object"""
2818
2728
            
2819
2729
            def __init__(self):
2821
2731
            
2822
2732
            _interface = "se.recompile.Mandos"
2823
2733
            
 
2734
            @dbus_interface_annotations(_interface)
 
2735
            def _foo(self):
 
2736
                return {
 
2737
                    "org.freedesktop.DBus.Property.EmitsChangedSignal":
 
2738
                    "false" }
 
2739
            
2824
2740
            @dbus.service.signal(_interface, signature="o")
2825
2741
            def ClientAdded(self, objpath):
2826
2742
                "D-Bus signal"