/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-ctl

  • Committer: Teddy Hogeborn
  • Date: 2019-08-01 17:35:45 UTC
  • Revision ID: teddy@recompile.se-20190801173545-swvm0c6e1e00qdwi
password-agent: Fix memory alignment issue

On many architectures (armel, armhf, mips, mips64el, mipsel, hppa,
ia64, sh4, and sparc64) GCC shows a warning when casting a "char *" to
a "struct inotify_event *"; The exact warning message from GCC is
"cast increases required alignment of target type [-Wcast-align]".

* dracut-module/password-agent.c (read_inotify_event): Change
  "ievent_buffer" to an anonymous struct instead of a char array.
  (test_read_inotify_event_IN_CLOSE_WRITE): - '' -
  (test_read_inotify_event_IN_MOVED_TO): - '' -
  (test_read_inotify_event_IN_DELETE): - '' -
  (test_read_inotify_event_IN_CLOSE_WRITE_badname): - '' -
  (test_read_inotify_event_IN_MOVED_TO_badname): - '' -
  (test_read_inotify_event_IN_DELETE_badname): - '' -

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/python3 -bbI
 
1
#!/usr/bin/python
2
2
# -*- after-save-hook: (lambda () (let ((command (if (fboundp 'file-local-name) (file-local-name (buffer-file-name)) (or (file-remote-p (buffer-file-name) 'localname) (buffer-file-name))))) (if (= (progn (if (get-buffer "*Test*") (kill-buffer "*Test*")) (process-file-shell-command (format "%s --check" (shell-quote-argument command)) nil "*Test*")) 0) (let ((w (get-buffer-window "*Test*"))) (if w (delete-window w))) (progn (with-current-buffer "*Test*" (compilation-mode)) (display-buffer "*Test*" '(display-buffer-in-side-window)))))); coding: utf-8 -*-
3
3
#
4
4
# Mandos Monitor - Control and monitor the Mandos server
46
46
import tempfile
47
47
import contextlib
48
48
 
49
 
if sys.version_info.major == 2:
50
 
    __metaclass__ = type
51
 
    str = unicode
52
 
 
53
 
class gi:
54
 
    """Dummy gi module, for the tests"""
55
 
    class repository:
56
 
        class GLib:
57
 
            class Error(Exception):
58
 
                pass
59
 
dbussy = None
60
 
ravel = None
61
 
dbus_python = None
62
 
pydbus = None
63
 
 
64
49
try:
65
 
    import dbussy
66
 
    import ravel
 
50
    import pydbus
 
51
    import gi
 
52
    dbus_python = None
67
53
except ImportError:
68
 
    try:
69
 
        import pydbus
70
 
        import gi
71
 
    except ImportError:
72
 
        import dbus as dbus_python
73
 
 
 
54
    import dbus as dbus_python
 
55
    pydbus = None
 
56
    class gi(object):
 
57
        """Dummy gi module, for the tests"""
 
58
        class repository(object):
 
59
            class GLib(object):
 
60
                class Error(Exception):
 
61
                    pass
74
62
 
75
63
# Show warnings by default
76
64
if not sys.warnoptions:
84
72
logging.captureWarnings(True)   # Show warnings via the logging system
85
73
 
86
74
if sys.version_info.major == 2:
 
75
    str = unicode
87
76
    import StringIO
88
77
    io.StringIO = StringIO.StringIO
89
78
 
90
79
locale.setlocale(locale.LC_ALL, "")
91
80
 
92
 
version = "1.8.9"
 
81
version = "1.8.5"
93
82
 
94
83
 
95
84
def main():
104
93
    if options.debug:
105
94
        log.setLevel(logging.DEBUG)
106
95
 
107
 
    if dbussy is not None and ravel is not None:
108
 
        bus = dbussy_adapter.CachingBus(dbussy, ravel)
109
 
    elif pydbus is not None:
 
96
    if pydbus is not None:
110
97
        bus = pydbus_adapter.CachingBus(pydbus)
111
98
    else:
112
99
        bus = dbus_python_adapter.CachingBus(dbus_python)
480
467
        parser.error("--remove can only be combined with --deny")
481
468
 
482
469
 
483
 
class dbus:
 
470
class dbus(object):
484
471
 
485
 
    class SystemBus:
 
472
    class SystemBus(object):
486
473
 
487
474
        object_manager_iface = "org.freedesktop.DBus.ObjectManager"
488
475
        def get_managed_objects(self, busname, objectpath):
497
484
                             self.properties_iface, interface, key,
498
485
                             value)
499
486
 
 
487
 
500
488
    class MandosBus(SystemBus):
501
489
        busname_domain = "se.recompile"
502
490
        busname = busname_domain + ".Mandos"
533
521
        pass
534
522
 
535
523
 
536
 
class dbus_python_adapter:
 
524
class dbus_python_adapter(object):
537
525
 
538
526
    class SystemBus(dbus.MandosBus):
539
527
        """Use dbus-python"""
593
581
                                     self.client_interface, key,
594
582
                                     value)
595
583
 
596
 
    class SilenceLogger:
 
584
    class SilenceLogger(object):
597
585
        "Simple context manager to silence a particular logger"
598
586
        def __init__(self, loggername):
599
587
            self.logger = logging.getLogger(loggername)
628
616
                return new_object
629
617
 
630
618
 
631
 
class pydbus_adapter:
 
619
class pydbus_adapter(object):
632
620
    class SystemBus(dbus.MandosBus):
633
621
        def __init__(self, module=pydbus):
634
622
            self.pydbus = module
691
679
                return new_object
692
680
 
693
681
 
694
 
class dbussy_adapter:
695
 
    class SystemBus(dbus.SystemBus):
696
 
        """Use DBussy"""
697
 
 
698
 
        def __init__(self, dbussy, ravel):
699
 
            self.dbussy = dbussy
700
 
            self.ravel = ravel
701
 
            self.bus = ravel.system_bus()
702
 
 
703
 
        @contextlib.contextmanager
704
 
        def convert_exception(self, exception_class=dbus.Error):
705
 
            try:
706
 
                yield
707
 
            except self.dbussy.DBusError as e:
708
 
                # This does what "raise from" would do
709
 
                exc = exception_class(*e.args)
710
 
                exc.__cause__ = e
711
 
                raise exc
712
 
 
713
 
        def call_method(self, methodname, busname, objectpath,
714
 
                        interface, *args):
715
 
            proxy_object = self.get_object(busname, objectpath)
716
 
            log.debug("D-Bus: %s:%s:%s.%s(%s)", busname, objectpath,
717
 
                      interface, methodname,
718
 
                      ", ".join(repr(a) for a in args))
719
 
            iface = proxy_object.get_interface(interface)
720
 
            method = getattr(iface, methodname)
721
 
            with self.convert_exception(dbus.Error):
722
 
                value =  method(*args)
723
 
            # DBussy returns values either as an empty list or as a
724
 
            # tuple: (signature, value)
725
 
            if value:
726
 
                return self.type_filter(value[0])
727
 
 
728
 
        def get_object(self, busname, objectpath):
729
 
            log.debug("D-Bus: Connect to: (busname=%r, path=%r)",
730
 
                      busname, objectpath)
731
 
            with self.convert_exception(dbus.ConnectFailed):
732
 
                return self.bus[busname][objectpath]
733
 
 
734
 
        def type_filter(self, value):
735
 
            """Convert the most bothersome types to Python types"""
736
 
            if isinstance(value, tuple):
737
 
                if (len(value) == 2
738
 
                    and isinstance(value[0],
739
 
                                   self.dbussy.DBUS.Signature)):
740
 
                    return self.type_filter(value[1])
741
 
            elif isinstance(value, self.dbussy.DBUS.ObjectPath):
742
 
                return str(value)
743
 
            # Also recurse into dictionaries
744
 
            elif isinstance(value, dict):
745
 
                return {self.type_filter(key):
746
 
                        self.type_filter(subval)
747
 
                        for key, subval in value.items()}
748
 
            return value
749
 
 
750
 
        def set_property(self, busname, objectpath, interface, key,
751
 
                         value):
752
 
            proxy_object = self.get_object(busname, objectpath)
753
 
            log.debug("D-Bus: %s:%s:%s.Set(%r, %r, %r)", busname,
754
 
                      objectpath, self.properties_iface, interface,
755
 
                      key, value)
756
 
            if key == "Secret":
757
 
                # DBussy wants a Byte Array to be a sequence of
758
 
                # values, not a byte string
759
 
                value = tuple(value)
760
 
            setattr(proxy_object.get_interface(interface), key, value)
761
 
 
762
 
    class MandosBus(SystemBus, dbus.MandosBus):
763
 
        pass
764
 
 
765
 
    class CachingBus(MandosBus):
766
 
        """A caching layer for dbussy_adapter.MandosBus"""
767
 
        def __init__(self, *args, **kwargs):
768
 
            self.object_cache = {}
769
 
            super(dbussy_adapter.CachingBus, self).__init__(*args,
770
 
                                                            **kwargs)
771
 
        def get_object(self, busname, objectpath):
772
 
            try:
773
 
                return self.object_cache[(busname, objectpath)]
774
 
            except KeyError:
775
 
                new_object = super(
776
 
                    dbussy_adapter.CachingBus,
777
 
                    self).get_object(busname, objectpath)
778
 
                self.object_cache[(busname, objectpath)]  = new_object
779
 
                return new_object
780
 
 
781
 
 
782
682
def commands_from_options(options):
783
683
 
784
684
    commands = list(options.commands)
812
712
    return commands
813
713
 
814
714
 
815
 
class command:
 
715
class command(object):
816
716
    """A namespace for command classes"""
817
717
 
818
 
    class Base:
 
718
    class Base(object):
819
719
        """Abstract base class for commands"""
820
720
        def run(self, clients, bus=None):
821
721
            """Normal commands should implement run_on_one_client(),
884
784
                keywords = self.all_keywords
885
785
            print(self.TableOfClients(clients.values(), keywords))
886
786
 
887
 
        class TableOfClients:
 
787
        class TableOfClients(object):
888
788
            tableheaders = {
889
789
                "Name": "Name",
890
790
                "Enabled": "Enabled",
1121
1021
                                                     "output"))
1122
1022
 
1123
1023
 
1124
 
class Unique:
 
1024
class Unique(object):
1125
1025
    """Class for objects which exist only to be unique objects, since
1126
1026
unittest.mock.sentinel only exists in Python 3.3"""
1127
1027
 
1411
1311
class Test_dbus_python_adapter_SystemBus(TestCaseWithAssertLogs):
1412
1312
 
1413
1313
    def MockDBusPython_func(self, func):
1414
 
        class mock_dbus_python:
 
1314
        class mock_dbus_python(object):
1415
1315
            """mock dbus-python module"""
1416
 
            class exceptions:
 
1316
            class exceptions(object):
1417
1317
                """Pseudo-namespace"""
1418
1318
                class DBusException(Exception):
1419
1319
                    pass
1420
 
            class SystemBus:
 
1320
            class SystemBus(object):
1421
1321
                @staticmethod
1422
1322
                def get_object(busname, objectpath):
1423
1323
                    DBusObject = collections.namedtuple(
1437
1337
                                    dbus_interface=dbus_interface)
1438
1338
                    return DBusObject(methodname=method,
1439
1339
                                      Set=set_property)
1440
 
            class Boolean:
 
1340
            class Boolean(object):
1441
1341
                def __init__(self, value):
1442
1342
                    self.value = bool(value)
1443
1343
                def __bool__(self):
1655
1555
            self.call_method(bus, "methodname", "busname",
1656
1556
                             "objectpath", "interface")
1657
1557
 
1658
 
    class fake_dbus_python_raises_exception_on_connect:
 
1558
    class fake_dbus_python_raises_exception_on_connect(object):
1659
1559
        """fake dbus-python module"""
1660
 
        class exceptions:
 
1560
        class exceptions(object):
1661
1561
            """Pseudo-namespace"""
1662
1562
            class DBusException(Exception):
1663
1563
                pass
1671
1571
 
1672
1572
 
1673
1573
class Test_dbus_python_adapter_CachingBus(unittest.TestCase):
1674
 
    class mock_dbus_python:
 
1574
    class mock_dbus_python(object):
1675
1575
        """mock dbus-python modules"""
1676
 
        class SystemBus:
 
1576
        class SystemBus(object):
1677
1577
            @staticmethod
1678
1578
            def get_object(busname, objectpath):
1679
1579
                return Unique()
1725
1625
class Test_pydbus_adapter_SystemBus(TestCaseWithAssertLogs):
1726
1626
 
1727
1627
    def Stub_pydbus_func(self, func):
1728
 
        class stub_pydbus:
 
1628
        class stub_pydbus(object):
1729
1629
            """stub pydbus module"""
1730
 
            class SystemBus:
 
1630
            class SystemBus(object):
1731
1631
                @staticmethod
1732
1632
                def get(busname, objectpath):
1733
1633
                    DBusObject = collections.namedtuple(
1779
1679
            self.call_method(bus, "methodname", "busname",
1780
1680
                             "objectpath", "interface")
1781
1681
 
1782
 
    class fake_pydbus_raises_exception_on_connect:
 
1682
    class fake_pydbus_raises_exception_on_connect(object):
1783
1683
        """fake dbus-python module"""
1784
1684
        @classmethod
1785
1685
        def SystemBus(cls):
1789
1689
            return Bus(get=get)
1790
1690
 
1791
1691
    def test_set_property_uses_setattr(self):
1792
 
        class Object:
 
1692
        class Object(object):
1793
1693
            pass
1794
1694
        obj = Object()
1795
 
        class pydbus_spy:
1796
 
            class SystemBus:
 
1695
        class pydbus_spy(object):
 
1696
            class SystemBus(object):
1797
1697
                @staticmethod
1798
1698
                def get(busname, objectpath):
1799
1699
                    return {"interface": obj}
1806
1706
    def test_get_suppresses_xml_deprecation_warning(self):
1807
1707
        if sys.version_info.major >= 3:
1808
1708
            return
1809
 
        class stub_pydbus_get:
1810
 
            class SystemBus:
 
1709
        class stub_pydbus_get(object):
 
1710
            class SystemBus(object):
1811
1711
                @staticmethod
1812
1712
                def get(busname, objectpath):
1813
1713
                    warnings.warn_explicit(
1821
1721
 
1822
1722
 
1823
1723
class Test_pydbus_adapter_CachingBus(unittest.TestCase):
1824
 
    class stub_pydbus:
 
1724
    class stub_pydbus(object):
1825
1725
        """stub pydbus module"""
1826
 
        class SystemBus:
 
1726
        class SystemBus(object):
1827
1727
            @staticmethod
1828
1728
            def get(busname, objectpath):
1829
1729
                return Unique()
1871
1771
        self.assertIs(obj1, obj1b)
1872
1772
 
1873
1773
 
1874
 
class Test_dbussy_adapter_SystemBus(TestCaseWithAssertLogs):
1875
 
 
1876
 
    class dummy_dbussy:
1877
 
        class DBUS:
1878
 
            class ObjectPath(str):
1879
 
                pass
1880
 
        class DBusError(Exception):
1881
 
            pass
1882
 
 
1883
 
    def fake_ravel_func(self, func):
1884
 
        class fake_ravel:
1885
 
            @staticmethod
1886
 
            def system_bus():
1887
 
                class DBusInterfaceProxy:
1888
 
                    @staticmethod
1889
 
                    def methodname(*args):
1890
 
                        return [func(*args)]
1891
 
                class DBusObject:
1892
 
                    @staticmethod
1893
 
                    def get_interface(interface):
1894
 
                        if interface == "interface":
1895
 
                            return DBusInterfaceProxy()
1896
 
                return {"busname": {"objectpath": DBusObject()}}
1897
 
        return fake_ravel
1898
 
 
1899
 
    def call_method(self, bus, methodname, busname, objectpath,
1900
 
                    interface, *args):
1901
 
        with self.assertLogs(log, logging.DEBUG):
1902
 
            return bus.call_method(methodname, busname, objectpath,
1903
 
                                   interface, *args)
1904
 
 
1905
 
    def test_call_method_returns(self):
1906
 
        expected_method_return = Unique()
1907
 
        method_args = (Unique(), Unique())
1908
 
        def func(*args):
1909
 
            self.assertEqual(len(method_args), len(args))
1910
 
            for marg, arg in zip(method_args, args):
1911
 
                self.assertIs(marg, arg)
1912
 
            return expected_method_return
1913
 
        fake_ravel = self.fake_ravel_func(func)
1914
 
        bus = dbussy_adapter.SystemBus(self.dummy_dbussy, fake_ravel)
1915
 
        ret = self.call_method(bus, "methodname", "busname",
1916
 
                               "objectpath", "interface",
1917
 
                               *method_args)
1918
 
        self.assertIs(ret, expected_method_return)
1919
 
 
1920
 
    def test_call_method_filters_objectpath(self):
1921
 
        def func():
1922
 
            return method_return
1923
 
        fake_ravel = self.fake_ravel_func(func)
1924
 
        bus = dbussy_adapter.SystemBus(self.dummy_dbussy, fake_ravel)
1925
 
        method_return = (self.dummy_dbussy.DBUS
1926
 
                         .ObjectPath("objectpath"))
1927
 
        ret = self.call_method(bus, "methodname", "busname",
1928
 
                               "objectpath", "interface")
1929
 
        self.assertEqual("objectpath", ret)
1930
 
        self.assertNotIsInstance(ret,
1931
 
                                 self.dummy_dbussy.DBUS.ObjectPath)
1932
 
 
1933
 
    def test_call_method_filters_objectpaths_in_dict(self):
1934
 
        ObjectPath = self.dummy_dbussy.DBUS.ObjectPath
1935
 
        def func():
1936
 
            return method_return
1937
 
        fake_ravel = self.fake_ravel_func(func)
1938
 
        bus = dbussy_adapter.SystemBus(self.dummy_dbussy, fake_ravel)
1939
 
        method_return = {
1940
 
            ObjectPath("objectpath_key_1"):
1941
 
            ObjectPath("objectpath_value_1"),
1942
 
            ObjectPath("objectpath_key_2"):
1943
 
            ObjectPath("objectpath_value_2"),
1944
 
        }
1945
 
        ret = self.call_method(bus, "methodname", "busname",
1946
 
                               "objectpath", "interface")
1947
 
        expected_method_return = {str(key): str(value)
1948
 
                                  for key, value in
1949
 
                                  method_return.items()}
1950
 
        for key, value in ret.items():
1951
 
            self.assertNotIsInstance(key, ObjectPath)
1952
 
            self.assertNotIsInstance(value, ObjectPath)
1953
 
        self.assertEqual(expected_method_return, ret)
1954
 
        self.assertIsInstance(ret, dict)
1955
 
 
1956
 
    def test_call_method_filters_objectpaths_in_dict_in_dict(self):
1957
 
        ObjectPath = self.dummy_dbussy.DBUS.ObjectPath
1958
 
        def func():
1959
 
            return method_return
1960
 
        fake_ravel = self.fake_ravel_func(func)
1961
 
        bus = dbussy_adapter.SystemBus(self.dummy_dbussy, fake_ravel)
1962
 
        method_return = {
1963
 
            ObjectPath("key1"): {
1964
 
                ObjectPath("key11"): ObjectPath("value11"),
1965
 
                ObjectPath("key12"): ObjectPath("value12"),
1966
 
            },
1967
 
            ObjectPath("key2"): {
1968
 
                ObjectPath("key21"): ObjectPath("value21"),
1969
 
                ObjectPath("key22"): ObjectPath("value22"),
1970
 
            },
1971
 
        }
1972
 
        ret = self.call_method(bus, "methodname", "busname",
1973
 
                               "objectpath", "interface")
1974
 
        expected_method_return = {
1975
 
            "key1": {"key11": "value11",
1976
 
                     "key12": "value12"},
1977
 
            "key2": {"key21": "value21",
1978
 
                     "key22": "value22"},
1979
 
        }
1980
 
        self.assertEqual(expected_method_return, ret)
1981
 
        for key, value in ret.items():
1982
 
            self.assertIsInstance(value, dict)
1983
 
            self.assertEqual(expected_method_return[key], value)
1984
 
            self.assertNotIsInstance(key, ObjectPath)
1985
 
            for inner_key, inner_value in value.items():
1986
 
                self.assertIsInstance(value, dict)
1987
 
                self.assertEqual(
1988
 
                    expected_method_return[key][inner_key],
1989
 
                    inner_value)
1990
 
                self.assertNotIsInstance(key, ObjectPath)
1991
 
 
1992
 
    def test_call_method_filters_objectpaths_in_dict_three_deep(self):
1993
 
        ObjectPath = self.dummy_dbussy.DBUS.ObjectPath
1994
 
        def func():
1995
 
            return method_return
1996
 
        fake_ravel = self.fake_ravel_func(func)
1997
 
        bus = dbussy_adapter.SystemBus(self.dummy_dbussy, fake_ravel)
1998
 
        method_return = {
1999
 
            ObjectPath("key1"): {
2000
 
                ObjectPath("key2"): {
2001
 
                    ObjectPath("key3"): ObjectPath("value"),
2002
 
                },
2003
 
            },
2004
 
        }
2005
 
        ret = self.call_method(bus, "methodname", "busname",
2006
 
                               "objectpath", "interface")
2007
 
        expected_method_return = {"key1": {"key2": {"key3": "value"}}}
2008
 
        self.assertEqual(expected_method_return, ret)
2009
 
        self.assertIsInstance(ret, dict)
2010
 
        self.assertNotIsInstance(next(iter(ret.keys())), ObjectPath)
2011
 
        self.assertIsInstance(ret["key1"], dict)
2012
 
        self.assertNotIsInstance(next(iter(ret["key1"].keys())),
2013
 
                                 ObjectPath)
2014
 
        self.assertIsInstance(ret["key1"]["key2"], dict)
2015
 
        self.assertNotIsInstance(
2016
 
            next(iter(ret["key1"]["key2"].keys())),
2017
 
            ObjectPath)
2018
 
        self.assertEqual("value", ret["key1"]["key2"]["key3"])
2019
 
        self.assertNotIsInstance(ret["key1"]["key2"]["key3"],
2020
 
                                 self.dummy_dbussy.DBUS.ObjectPath)
2021
 
 
2022
 
    def test_call_method_handles_exception(self):
2023
 
        def func():
2024
 
            raise self.dummy_dbussy.DBusError()
2025
 
 
2026
 
        fake_ravel = self.fake_ravel_func(func)
2027
 
        bus = dbussy_adapter.SystemBus(self.dummy_dbussy, fake_ravel)
2028
 
 
2029
 
        with self.assertRaises(dbus.Error) as e:
2030
 
            self.call_method(bus, "methodname", "busname",
2031
 
                             "objectpath", "interface")
2032
 
 
2033
 
        self.assertNotIsInstance(e.exception, dbus.ConnectFailed)
2034
 
 
2035
 
    def test_get_object_converts_to_correct_exception(self):
2036
 
        class fake_ravel_raises_exception_on_connect:
2037
 
            @staticmethod
2038
 
            def system_bus():
2039
 
                class Bus:
2040
 
                    @staticmethod
2041
 
                    def __getitem__(key):
2042
 
                        if key == "objectpath":
2043
 
                            raise self.dummy_dbussy.DBusError()
2044
 
                        raise Exception(key)
2045
 
                return {"busname": Bus()}
2046
 
        def func():
2047
 
            raise self.dummy_dbussy.DBusError()
2048
 
        bus = dbussy_adapter.SystemBus(
2049
 
            self.dummy_dbussy,
2050
 
            fake_ravel_raises_exception_on_connect)
2051
 
        with self.assertRaises(dbus.ConnectFailed):
2052
 
            self.call_method(bus, "methodname", "busname",
2053
 
                             "objectpath", "interface")
2054
 
 
2055
 
 
2056
1774
class Test_commands_from_options(unittest.TestCase):
2057
1775
 
2058
1776
    def setUp(self):