Hello, Am Sonntag, 23. November 2014 schrieb Christian Boltz: > Am Samstag, 22. November 2014 schrieb Christian Boltz: > > The updated patch (v2) is attached. > > Here's v3 ;-)
And here's v4 :-) Changes since v3: - update various tests after changing capability to set() - use obj.set_param in test_space_cap() - add test_equal() Regards, Christian Boltz -- > [...] is currently down due to a failure in the NAS system. > [...] > your NAS (network attached storage) Oh. I thought it stood for Networked Adrian Schröter :D [> Adrian Schröter and Jean Delvare in opensuse-buildservice]
=== added file 'utils/test/test-capability.py' --- utils/test/test-capability.py 1970-01-01 00:00:00 +0000 +++ utils/test/test-capability.py 2014-11-27 19:57:17 +0000 @@ -0,0 +1,806 @@ +#!/usr/bin/env python +# ---------------------------------------------------------------------- +# Copyright (C) 2014 Christian Boltz <[email protected]> +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of version 2 of the GNU General Public +# License as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# ---------------------------------------------------------------------- + +import unittest + +from apparmor.rule.capability import CapabilityRule, CapabilityRuleset +from apparmor.common import AppArmorException, AppArmorBug, hasher +from apparmor.logparser import ReadLog + +import re + +# --- tests for single CapabilityRule --- # + +class CapabilityTest(unittest.TestCase): + def setUp(self): + self.maxDiff = None + + def _compare_obj_with_rawrule(self, rawrule, expected): + + obj = CapabilityRule() + obj.set_raw(rawrule) + + self.assertEqual(rawrule.strip(), obj.rawrule) + + self._compare_obj(obj, expected) + + def _compare_obj(self, obj, expected): + self.assertEqual(expected['allow_keyword'], obj.allow_keyword) + self.assertEqual(expected['audit'], obj.audit) + self.assertEqual(expected['capability'], obj.capability) + self.assertEqual(expected['all_caps'], obj.all_caps) + self.assertEqual(expected['deny'], obj.deny) + self.assertEqual(expected['inlinecomment'], obj.inlinecomment) + + def test_cap_allow_all(self): + self._compare_obj_with_rawrule("capability,", { + 'allow_keyword': False, + 'deny': False, + 'audit': False, + 'capability': set(), + 'all_caps': True, + 'inlinecomment': "", + }) + + def test_cap_allow_sys_admin(self): + self._compare_obj_with_rawrule("capability sys_admin,", { + 'allow_keyword': False, + 'deny': False, + 'audit': False, + 'capability': {'sys_admin'}, + 'all_caps': False, + 'inlinecomment': "", + }) + + def test_cap_deny_sys_admin(self): + self._compare_obj_with_rawrule(" deny capability sys_admin, # some comment", { + 'allow_keyword': False, + 'deny': True, + 'audit': False, + 'capability': {'sys_admin'}, + 'all_caps': False, + 'inlinecomment': " # some comment", + }) + + def test_cap_multi(self): + self._compare_obj_with_rawrule("capability sys_admin dac_override,", { + 'allow_keyword': False, + 'deny': False, + 'audit': False, + 'capability': {'sys_admin', 'dac_override'}, + 'all_caps': False, + 'inlinecomment': "", + }) + + # Template for test_cap_* functions + # def test_cap_(self): + # self._compare_obj_with_rawrule("capability,", { + # 'allow_keyword': False, + # 'deny': False, + # 'audit': False, + # 'capability': set(), # (or {'foo'} if not empty) + # 'all_caps': False, + # 'inlinecomment': "", + # }) + + def test_cap_from_log(self): + parser = ReadLog('', '', '', '', '') + event = 'type=AVC msg=audit(1415403814.628:662): apparmor="ALLOWED" operation="capable" profile="/bin/ping" pid=15454 comm="ping" capability=13 capname="net_raw"' + + parsed_event = parser.parse_event(event) + + self.assertEqual(parsed_event, { + 'request_mask': set(), + 'denied_mask': set(), + 'magic_token': 0, + 'parent': 0, + 'profile': '/bin/ping', + 'operation': 'capable', + 'resource': None, + 'info': None, + 'aamode': 'PERMITTING', + 'time': 1415403814, + 'active_hat': None, + 'pid': 15454, + 'task': 0, + 'attr': None, + 'name2': None, + 'name': 'net_raw' + }) + + obj = CapabilityRule() + obj.set_log(parsed_event) + + self._compare_obj(obj, { + 'allow_keyword': False, + 'deny': False, + 'audit': False, + 'capability': {'net_raw'}, + 'all_caps': False, + 'inlinecomment': "", + }) + + self.assertEqual(obj.get_raw(1), ' capability net_raw,') + + def test_cap_from_invalid_log(self): + parser = ReadLog('', '', '', '', '') + # invalid log entry, name= should contain the capability name + event = 'type=AVC msg=audit(1415403814.628:662): apparmor="ALLOWED" operation="capable" profile="/bin/ping" pid=15454 comm="ping" capability=13 capname=""' + + parsed_event = parser.parse_event(event) + + obj = CapabilityRule() + + with self.assertRaises(AppArmorBug): + obj.set_log(parsed_event) + + with self.assertRaises(AppArmorBug): + obj.get_raw(1) + + def test_cap_from_non_cap_log(self): + parser = ReadLog('', '', '', '', '') + # log entry for different rule type + event = 'type=AVC msg=audit(1415403814.973:667): apparmor="ALLOWED" operation="setsockopt" profile="/home/sys-tmp/ping" pid=15454 comm="ping" lport=1 family="inet" sock_type="raw" protocol=1' + + parsed_event = parser.parse_event(event) + + obj = CapabilityRule() + + with self.assertRaises(AppArmorBug): + obj.set_log(parsed_event) + + with self.assertRaises(AppArmorBug): + obj.get_raw(1) + + def test_cap_from_param(self): + obj = CapabilityRule() + obj.set_param('chown') + + self._compare_obj(obj, { + 'allow_keyword': False, + 'deny': False, + 'audit': False, + 'capability': {'chown'}, + 'all_caps': False, + 'inlinecomment': "", + }) + + def test_cap_from_param_2(self): + obj = CapabilityRule() + obj.set_param('chown', audit=True, deny=True) + + self._compare_obj(obj, { + 'allow_keyword': False, + 'deny': True, + 'audit': True, + 'capability': {'chown'}, + 'all_caps': False, + 'inlinecomment': "", + }) + + +class InvalidCapabilityTest(unittest.TestCase): + def setUp(self): + self.maxDiff = None + + def _check_invalid_rawrule(self, rawrule): + obj = CapabilityRule() + with self.assertRaises(AppArmorException): + obj.set_raw(rawrule) + + def test_invalid_cap_missing_comma(self): + self._check_invalid_rawrule('capability') # missing comma + + def test_invalid_cap_non_CapabilityRule(self): + self._check_invalid_rawrule('network,') # not a capability rule + + def test_empty_cap_list(self): + obj = CapabilityRule() + # no capability set, and ALL not set + with self.assertRaises(AppArmorBug): + obj.get_clean(1) + + def test_space_cap(self): + obj = CapabilityRule() + obj.set_param(' ') # the whitespace capability ;-) + with self.assertRaises(AppArmorBug): + obj.get_clean(1) + + def test_parse_audit_allow_invalid(self): + obj = CapabilityRule() + + regex = re.compile('^\s*(?P<audit>audit\s+)?(?P<allow>allow\s+|deny\s+|invalid\s+)?') + matches = regex.search('audit invalid ') + + with self.assertRaises(AppArmorBug): + obj.parse_audit_allow(matches) + + +class WriteCapabilityTest(unittest.TestCase): + def setUp(self): + self.maxDiff = None + + def _check_write_rule(self, rawrule, cleanrule): + obj = CapabilityRule() + obj.set_raw(rawrule) + clean = obj.get_clean(0) + raw = obj.get_raw(0) + + self.assertEqual(cleanrule.strip(), clean, 'unexpected clean rule') + self.assertEqual(rawrule.strip(), raw, 'unexpected raw rule') + + def test_write_all(self): + self._check_write_rule(' capability , # foo ', 'capability, # foo') + + def test_write_sys_admin(self): + self._check_write_rule(' audit capability sys_admin,', 'audit capability sys_admin,') + + def test_write_sys_multi(self): + self._check_write_rule(' deny capability sys_admin audit_write,# foo bar', 'deny capability audit_write sys_admin, # foo bar') + + def test_write_manually(self): + obj = CapabilityRule() + obj.capability = {'ptrace', 'audit_write'} + obj.allow_keyword = True + + expected = ' allow capability audit_write ptrace,' + + self.assertEqual(expected, obj.get_clean(2), 'unexpected clean rule') + self.assertEqual(expected, obj.get_raw(2), 'unexpected raw rule') + +class CapabilityCoveredTest(unittest.TestCase): + def setUp(self): + self.maxDiff = None + + def _init_obj_with_rawrule(self, rawrule): + obj = CapabilityRule() + obj.set_raw(rawrule) + return obj + + def _is_covered(self, obj, rule_to_test): + return obj.is_covered(self._init_obj_with_rawrule(rule_to_test)) + + def _is_covered_exact(self, obj, rule_to_test): + return obj.is_covered(self._init_obj_with_rawrule(rule_to_test), True, True) + + def _is_equal(self, obj, rule_to_test, strict): + return obj.is_equal(self._init_obj_with_rawrule(rule_to_test), strict) + + def test_covered_single(self): + obj = self._init_obj_with_rawrule('capability sys_admin,') + + self.assertTrue(self._is_covered(obj, 'capability sys_admin,')) + + self.assertFalse(self._is_covered(obj, 'audit capability sys_admin,')) + self.assertFalse(self._is_covered(obj, 'audit capability,')) + self.assertFalse(self._is_covered(obj, 'capability chown,')) + self.assertFalse(self._is_covered(obj, 'capability,')) + + def test_covered_audit(self): + obj = self._init_obj_with_rawrule('audit capability sys_admin,') + + self.assertTrue(self._is_covered(obj, 'capability sys_admin,')) + self.assertTrue(self._is_covered(obj, 'audit capability sys_admin,')) + + self.assertFalse(self._is_covered(obj, 'audit capability,')) + self.assertFalse(self._is_covered(obj, 'capability chown,')) + self.assertFalse(self._is_covered(obj, 'capability,')) + + def test_covered_check_audit(self): + obj = self._init_obj_with_rawrule('audit capability sys_admin,') + + self.assertFalse(self._is_covered_exact(obj, 'capability sys_admin,')) + self.assertTrue(self._is_covered_exact(obj, 'audit capability sys_admin,')) + + self.assertFalse(self._is_covered_exact(obj, 'audit capability,')) + self.assertFalse(self._is_covered_exact(obj, 'capability chown,')) + self.assertFalse(self._is_covered_exact(obj, 'capability,')) + + def test_equal(self): + obj = self._init_obj_with_rawrule('capability sys_admin,') + + self.assertTrue(self._is_equal(obj, 'capability sys_admin,', True)) + self.assertFalse(self._is_equal(obj, 'allow capability sys_admin,', True)) + self.assertFalse(self._is_equal(obj, 'allow capability sys_admin,', True)) + self.assertFalse(self._is_equal(obj, 'audit capability sys_admin,', True)) + + self.assertTrue(self._is_equal(obj, 'capability sys_admin,', False)) + self.assertTrue(self._is_equal(obj, 'allow capability sys_admin,', False)) + self.assertFalse(self._is_equal(obj, 'audit capability sys_admin,', False)) + + def test_covered_multi(self): + obj = self._init_obj_with_rawrule('capability audit_write sys_admin,') + + self.assertTrue(self._is_covered(obj, 'capability sys_admin,')) + self.assertTrue(self._is_covered(obj, 'capability audit_write,')) + self.assertTrue(self._is_covered(obj, 'capability audit_write sys_admin,')) + self.assertTrue(self._is_covered(obj, 'capability sys_admin audit_write,')) + + self.assertFalse(self._is_covered(obj, 'audit capability,')) + self.assertFalse(self._is_covered(obj, 'capability chown,')) + self.assertFalse(self._is_covered(obj, 'capability,')) + + def test_covered_all(self): + obj = self._init_obj_with_rawrule('capability,') + + self.assertTrue(self._is_covered(obj, 'capability sys_admin,')) + self.assertTrue(self._is_covered(obj, 'capability audit_write,')) + self.assertTrue(self._is_covered(obj, 'capability audit_write sys_admin,')) + self.assertTrue(self._is_covered(obj, 'capability sys_admin audit_write,')) + self.assertTrue(self._is_covered(obj, 'capability,')) + + self.assertFalse(self._is_covered(obj, 'audit capability,')) + + def test_covered_deny(self): + obj = self._init_obj_with_rawrule('capability sys_admin,') + + self.assertTrue(self._is_covered(obj, 'capability sys_admin,')) + + self.assertFalse(self._is_covered(obj, 'audit deny capability sys_admin,')) + self.assertFalse(self._is_covered(obj, 'deny capability sys_admin,')) + self.assertFalse(self._is_covered(obj, 'capability chown,')) + self.assertFalse(self._is_covered(obj, 'capability,')) + + def test_covered_deny_2(self): + obj = self._init_obj_with_rawrule('deny capability sys_admin,') + + self.assertTrue(self._is_covered(obj, 'deny capability sys_admin,')) + + self.assertFalse(self._is_covered(obj, 'audit deny capability sys_admin,')) + self.assertFalse(self._is_covered(obj, 'capability sys_admin,')) + self.assertFalse(self._is_covered(obj, 'deny capability chown,')) + self.assertFalse(self._is_covered(obj, 'deny capability,')) + + def test_invalid_is_obj_covered(self): + obj = self._init_obj_with_rawrule('capability sys_admin,') + + testobj = CapabilityRule() # no capability set + + with self.assertRaises(AppArmorBug): + obj.is_covered(testobj) + + def test_empty_init(self): + # add to internal set instead of using .set_* (which overwrites the internal set) to make sure obj and obj2 use separate storage + obj = CapabilityRule() + obj.capability.add('sys_admin') + + obj2 = CapabilityRule() + obj2.capability.add('ptrace') + + self.assertFalse(self._is_covered(obj2, 'capability sys_admin,')) + self.assertTrue(self._is_covered(obj2, 'capability ptrace,')) + +# --- tests for CapabilityRuleset --- # + +class CapabilityRulesTest(unittest.TestCase): + def setUp(self): + self.maxDiff = None + + def test_empty_ruleset(self): + ruleset = CapabilityRuleset() + ruleset_2 = CapabilityRuleset() + self.assertEqual([], ruleset.get_raw(2)) + self.assertEqual([], ruleset.get_clean(2)) + self.assertEqual([], ruleset_2.get_raw(2)) + self.assertEqual([], ruleset_2.get_clean(2)) + + def test_ruleset_1(self): + ruleset = CapabilityRuleset() + rules = [ + 'capability sys_admin,', + 'capability chown,', + ] + + expected_raw = [ + 'capability sys_admin,', + 'capability chown,', + '', + ] + + expected_clean = [ + 'capability chown,', + 'capability sys_admin,', + '', + ] + + for rule in rules: + ruleset.add_raw(rule) + + self.assertEqual(expected_raw, ruleset.get_raw(0)) + self.assertEqual(expected_clean, ruleset.get_clean(0)) + + def test_ruleset_2(self): + ruleset = CapabilityRuleset() + rules = [ + 'capability chown,', + 'allow capability sys_admin,', + 'deny capability chgrp, # example comment', + ] + + expected_raw = [ + ' capability chown,', + ' allow capability sys_admin,', + ' deny capability chgrp, # example comment', + '', + ] + + expected_clean = [ + ' deny capability chgrp, # example comment', + '', + ' allow capability sys_admin,', + ' capability chown,', + '', + ] + + for rule in rules: + ruleset.add_raw(rule) + + self.assertEqual(expected_raw, ruleset.get_raw(1)) + self.assertEqual(expected_clean, ruleset.get_clean(1)) + + def test_ruleset_add_obj(self): + rule_obj = CapabilityRule() + rule_obj.set_raw('capability chgrp, # example comment') + + ruleset = CapabilityRuleset() + ruleset.add_obj(rule_obj) + + expected_raw = [ + ' capability chgrp, # example comment', + '', + ] + + expected_clean = expected_raw + + self.assertEqual(expected_raw, ruleset.get_raw(1)) + self.assertEqual(expected_clean, ruleset.get_clean(1)) + + +class CapabilityRulesCoveredTest(unittest.TestCase): + def setUp(self): + self.maxDiff = None + + self.ruleset = CapabilityRuleset() + rules = [ + 'capability chown,', + 'capability setuid setgid,', + 'allow capability sys_admin,', + 'audit capability kill,', + 'deny capability chgrp, # example comment', + ] + + for rule in rules: + self.ruleset.add_raw(rule) + + def test_ruleset_is_raw_covered_1(self): + self.assertTrue(self.ruleset.is_raw_covered('capability chown,')) + def test_ruleset_is_raw_covered_2(self): + self.assertTrue(self.ruleset.is_raw_covered('capability sys_admin,')) + def test_ruleset_is_raw_covered_3(self): + self.assertTrue(self.ruleset.is_raw_covered('allow capability sys_admin,')) + def test_ruleset_is_raw_covered_4(self): + self.assertTrue(self.ruleset.is_raw_covered('capability setuid,')) + def test_ruleset_is_raw_covered_5(self): + self.assertTrue(self.ruleset.is_raw_covered('allow capability setgid,')) + def test_ruleset_is_raw_covered_6(self): + self.assertTrue(self.ruleset.is_raw_covered('capability setgid setuid,')) + def test_ruleset_is_raw_covered_7(self): + pass # self.assertTrue(self.ruleset.is_raw_covered('capability sys_admin chown,')) # fails because it is split over two rule objects internally + def test_ruleset_is_raw_covered_8(self): + self.assertTrue(self.ruleset.is_raw_covered('capability kill,')) + + def test_ruleset_is_raw_covered_9(self): + self.assertFalse(self.ruleset.is_raw_covered('deny capability chown,')) + def test_ruleset_is_raw_covered_10(self): + self.assertFalse(self.ruleset.is_raw_covered('deny capability sys_admin,')) + def test_ruleset_is_raw_covered_11(self): + self.assertFalse(self.ruleset.is_raw_covered('deny capability sys_admin chown,')) + def test_ruleset_is_raw_covered_12(self): + self.assertFalse(self.ruleset.is_raw_covered('deny capability setgid,')) + def test_ruleset_is_raw_covered_13(self): + self.assertFalse(self.ruleset.is_raw_covered('deny capability kill,')) + + def test_ruleset_is_raw_covered_14(self): + self.assertFalse(self.ruleset.is_raw_covered('audit capability chown,')) + def test_ruleset_is_raw_covered_15(self): + self.assertFalse(self.ruleset.is_raw_covered('audit capability sys_admin,')) + def test_ruleset_is_raw_covered_16(self): + self.assertFalse(self.ruleset.is_raw_covered('audit capability sys_admin chown,')) + def test_ruleset_is_raw_covered_17(self): + self.assertFalse(self.ruleset.is_raw_covered('audit capability setgid,')) + def test_ruleset_is_raw_covered_18(self): + self.assertTrue(self.ruleset.is_raw_covered('audit capability kill,')) + + def test_ruleset_is_raw_covered_19(self): + self.assertTrue(self.ruleset.is_raw_covered('deny capability chgrp,')) + def test_ruleset_is_raw_covered_20(self): + self.assertFalse(self.ruleset.is_raw_covered('audit deny capability chgrp,')) + def test_ruleset_is_raw_covered_21(self): + self.assertFalse(self.ruleset.is_raw_covered('audit capability chgrp,')) + + def _test_log_covered(self, expected, capability): + event_base = 'type=AVC msg=audit(1415403814.628:662): apparmor="ALLOWED" operation="capable" profile="/bin/ping" pid=15454 comm="ping" capability=13 capname="%s"' + + parser = ReadLog('', '', '', '', '') + self.assertEqual(expected, self.ruleset.is_log_covered(parser.parse_event(event_base%capability))) + + def test_ruleset_is_log_covered_1(self): + self._test_log_covered(False, 'net_raw') + def test_ruleset_is_log_covered_2(self): + self._test_log_covered(True, 'chown') + def test_ruleset_is_log_covered_3(self): + self._test_log_covered(True, 'sys_admin') + def test_ruleset_is_log_covered_4(self): + self._test_log_covered(True, 'kill') + def test_ruleset_is_log_covered_5(self): + self._test_log_covered(False, 'chgrp') + def test_ruleset_is_log_covered_6(self): + event_base = 'type=AVC msg=audit(1415403814.628:662): apparmor="ALLOWED" operation="capable" profile="/bin/ping" pid=15454 comm="ping" capability=13 capname="%s"' + + parser = ReadLog('', '', '', '', '') + self.assertEqual(True, self.ruleset.is_log_covered(parser.parse_event(event_base%'chgrp'), False)) # ignores allow/deny + +class CapabilityGlobTest(unittest.TestCase): + def setUp(self): + self.maxDiff = None + self.ruleset = CapabilityRuleset() + + def test_glob(self): + self.assertEqual(self.ruleset.get_glob('capability net_raw,'), 'capability,') + + def test_glob_ext(self): + with self.assertRaises(AppArmorBug): + self.ruleset.get_glob_ext('capability net_raw,') + +class CapabilityDeleteTest(unittest.TestCase): + def setUp(self): + self.maxDiff = None + + self.ruleset = CapabilityRuleset() + rules = [ + 'capability chown,', + 'allow capability sys_admin,', + 'deny capability chgrp, # example comment', + ] + + for rule in rules: + self.ruleset.add_raw(rule) + + def test_delete_raw(self): + expected_raw = [ + ' capability chown,', + ' deny capability chgrp, # example comment', + '', + ] + + expected_clean = [ + ' deny capability chgrp, # example comment', + '', + ' capability chown,', + '', + ] + + self.ruleset.delete_raw('capability sys_admin,') + + self.assertEqual(expected_raw, self.ruleset.get_raw(1)) + self.assertEqual(expected_clean, self.ruleset.get_clean(1)) + + def test_delete_raw_with_allcaps(self): + expected_raw = [ + ' capability chown,', + ' deny capability chgrp, # example comment', + ' capability,', + '', + ] + + expected_clean = [ + ' deny capability chgrp, # example comment', + '', + ' capability chown,', + ' capability,', + '', + ] + + self.ruleset.add_raw('capability,') + self.ruleset.delete_raw('capability sys_admin,') + + self.assertEqual(expected_raw, self.ruleset.get_raw(1)) + self.assertEqual(expected_clean, self.ruleset.get_clean(1)) + + def test_delete_raw_with_multi(self): + expected_raw = [ + ' capability chown,', + ' allow capability sys_admin,', + ' deny capability chgrp, # example comment', + '', + ] + + expected_clean = [ + ' deny capability chgrp, # example comment', + '', + ' allow capability sys_admin,', + ' capability chown,', + '', + ] + + self.ruleset.add_raw('capability audit_read audit_write,') + self.ruleset.delete_raw('capability audit_read audit_write,') + + self.assertEqual(expected_raw, self.ruleset.get_raw(1)) + self.assertEqual(expected_clean, self.ruleset.get_clean(1)) + + def test_delete_raw_with_multi_2(self): + self.ruleset.add_raw('capability audit_read audit_write,') + + with self.assertRaises(AppArmorBug): + # XXX ideally delete_raw should remove audit_read from the "capability audit_read audit_write," ruleset + # but that's quite some work to cover a corner case. + self.ruleset.delete_raw('capability audit_read,') + + def test_delete_raw_notfound(self): + with self.assertRaises(AppArmorBug): + self.ruleset.delete_raw('capability audit_write,') + + def test_delete_duplicates(self): + inc = CapabilityRuleset() + rules = [ + 'capability chown,', + 'deny capability chgrp, # example comment', + ] + + for rule in rules: + inc.add_raw(rule) + + expected_raw = [ + ' allow capability sys_admin,', + '', + ] + + expected_clean = expected_raw + + self.assertEqual(self.ruleset.delete_duplicates(inc), 2) + self.assertEqual(expected_raw, self.ruleset.get_raw(1)) + self.assertEqual(expected_clean, self.ruleset.get_clean(1)) + + def test_delete_duplicates_2(self): + inc = CapabilityRuleset() + rules = [ + 'capability audit_write,', + 'capability chgrp, # example comment', + ] + + for rule in rules: + inc.add_raw(rule) + + expected_raw = [ + ' capability chown,', + ' allow capability sys_admin,', + ' deny capability chgrp, # example comment', + '', + ] + + expected_clean = [ + ' deny capability chgrp, # example comment', + '', + ' allow capability sys_admin,', + ' capability chown,', + '', + ] + + self.assertEqual(self.ruleset.delete_duplicates(inc), 0) + self.assertEqual(expected_raw, self.ruleset.get_raw(1)) + self.assertEqual(expected_clean, self.ruleset.get_clean(1)) + + def test_delete_duplicates_3(self): + self.ruleset.add_raw('audit capability dac_override,') + + inc = CapabilityRuleset() + rules = [ + 'capability dac_override,', + ] + + for rule in rules: + inc.add_raw(rule) + + expected_raw = [ + ' capability chown,', + ' allow capability sys_admin,', + ' deny capability chgrp, # example comment', + ' audit capability dac_override,', + '', + ] + + expected_clean = [ + ' deny capability chgrp, # example comment', + '', + ' allow capability sys_admin,', + ' audit capability dac_override,', + ' capability chown,', + '', + ] + + self.assertEqual(self.ruleset.delete_duplicates(inc), 0) + self.assertEqual(expected_raw, self.ruleset.get_raw(1)) + self.assertEqual(expected_clean, self.ruleset.get_clean(1)) + + def test_delete_duplicates_4(self): + inc = CapabilityRuleset() + rules = [ + 'capability,', + ] + + for rule in rules: + inc.add_raw(rule) + + expected_raw = [ + ' allow capability sys_admin,', # XXX huh? should be deleted! + ' deny capability chgrp, # example comment', + '', + ] + + expected_clean = [ + ' deny capability chgrp, # example comment', + '', + ' allow capability sys_admin,', # XXX huh? should be deleted! + '', + ] + + self.assertEqual(self.ruleset.delete_duplicates(inc), 1) + self.assertEqual(expected_raw, self.ruleset.get_raw(1)) + self.assertEqual(expected_clean, self.ruleset.get_clean(1)) + + def test_delete_duplicates_none(self): + expected_raw = [ + ' capability chown,', + ' allow capability sys_admin,', + ' deny capability chgrp, # example comment', + '', + ] + + expected_clean = [ + ' deny capability chgrp, # example comment', + '', + ' allow capability sys_admin,', + ' capability chown,', + '', + ] + + self.assertEqual(self.ruleset.delete_duplicates(None), 0) + self.assertEqual(expected_raw, self.ruleset.get_raw(1)) + self.assertEqual(expected_clean, self.ruleset.get_clean(1)) + + def test_delete_duplicates_hasher(self): + expected_raw = [ + ' capability chown,', + ' allow capability sys_admin,', + ' deny capability chgrp, # example comment', + '', + ] + + expected_clean = [ + ' deny capability chgrp, # example comment', + '', + ' allow capability sys_admin,', + ' capability chown,', + '', + ] + + self.assertEqual(self.ruleset.delete_duplicates(hasher()), 0) + self.assertEqual(expected_raw, self.ruleset.get_raw(1)) + self.assertEqual(expected_clean, self.ruleset.get_clean(1)) + + +if __name__ == "__main__": + unittest.main(verbosity=2)
-- AppArmor mailing list [email protected] Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor
