diff --git a/sesearch b/sesearch index f4421db..97d5b98 100755 --- a/sesearch +++ b/sesearch @@ -69,10 +69,10 @@ rtypes.add_argument("--type_member", action="append_const", help="Search type_member rules.") rbacrtypes = parser.add_argument_group("RBAC Rule Types") rbacrtypes.add_argument("--role_allow", action="append_const", - const="allow", dest="rbacrtypes", + const=setools.RBACRuletype.allow, dest="rbacrtypes", help="Search role allow rules.") rbacrtypes.add_argument("--role_trans", action="append_const", - const="role_transition", dest="rbacrtypes", + const=setools.RBACRuletype.role_transition, dest="rbacrtypes", help="Search role_transition rules.") mlsrtypes = parser.add_argument_group("MLS Rule Types") diff --git a/setools/diff/rbacrules.py b/setools/diff/rbacrules.py index 81be013..95b15c4 100644 --- a/setools/diff/rbacrules.py +++ b/setools/diff/rbacrules.py @@ -18,6 +18,7 @@ # from collections import defaultdict, namedtuple +from ..policyrep import RBACRuletype from .descriptors import DiffResultDescriptor from .difference import Difference, SymbolWrapper, Wrapper @@ -54,8 +55,8 @@ class RBACRulesDifference(Difference): self._create_rbac_rule_lists() self.added_role_allows, self.removed_role_allows, _ = self._set_diff( - self._expand_generator(self._left_rbac_rules["allow"], RoleAllowWrapper), - self._expand_generator(self._right_rbac_rules["allow"], RoleAllowWrapper)) + self._expand_generator(self._left_rbac_rules[RBACRuletype.allow], RoleAllowWrapper), + self._expand_generator(self._right_rbac_rules[RBACRuletype.allow], RoleAllowWrapper)) def diff_role_transitions(self): """Generate the difference in role_transition rules between the policies.""" @@ -68,8 +69,9 @@ class RBACRulesDifference(Difference): self._create_rbac_rule_lists() added, removed, matched = self._set_diff( - self._expand_generator(self._left_rbac_rules["role_transition"], RoleTransitionWrapper), - self._expand_generator(self._right_rbac_rules["role_transition"], + self._expand_generator(self._left_rbac_rules[RBACRuletype.role_transition], + RoleTransitionWrapper), + self._expand_generator(self._right_rbac_rules[RBACRuletype.role_transition], RoleTransitionWrapper)) modified = [] diff --git a/setools/policyrep/__init__.py b/setools/policyrep/__init__.py index 557e29e..4ef9f0a 100644 --- a/setools/policyrep/__init__.py +++ b/setools/policyrep/__init__.py @@ -23,6 +23,7 @@ from . import exception from .netcontext import PortconProtocol, PortconRange +from .rbacrule import RBACRuletype from .selinuxpolicy import SELinuxPolicy from .terule import IoctlSet, TERuletype from .xencontext import IomemconRange, IoportconRange diff --git a/setools/policyrep/rbacrule.py b/setools/policyrep/rbacrule.py index e923162..c51632c 100644 --- a/setools/policyrep/rbacrule.py +++ b/setools/policyrep/rbacrule.py @@ -1,4 +1,5 @@ # Copyright 2014, 2016, Tresys Technology, LLC +# Copyright 2016, Chris PeBenito # # This file is part of SETools. # @@ -23,6 +24,7 @@ from . import qpol from . import rule from . import role from . import typeattr +from .util import PolicyEnum def rbac_rule_factory(policy, name): @@ -62,10 +64,18 @@ def expanded_rbac_rule_factory(original, source, target): def validate_ruletype(t): """Validate RBAC rule types.""" - if t not in ["allow", "role_transition"]: + try: + return RBACRuletype.lookup(t) + except KeyError: raise exception.InvalidRBACRuleType("{0} is not a valid RBAC rule type.".format(t)) - return t + +class RBACRuletype(PolicyEnum): + + """An enumeration of RBAC rule types.""" + + allow = 1 + role_transition = 2 class RoleAllow(rule.PolicyRule): @@ -78,7 +88,7 @@ class RoleAllow(rule.PolicyRule): def __hash__(self): return hash("{0.ruletype}|{0.source}|{0.target}".format(self)) - ruletype = "allow" + ruletype = RBACRuletype.allow @property def source(self): @@ -113,7 +123,7 @@ class RoleTransition(rule.PolicyRule): def __str__(self): return "{0.ruletype} {0.source} {0.target}:{0.tclass} {0.default};".format(self) - ruletype = "role_transition" + ruletype = RBACRuletype.role_transition @property def source(self): diff --git a/setools/policyrep/selinuxpolicy.py b/setools/policyrep/selinuxpolicy.py index 3e5019f..637ca1d 100644 --- a/setools/policyrep/selinuxpolicy.py +++ b/setools/policyrep/selinuxpolicy.py @@ -608,6 +608,8 @@ class SELinuxPolicy(object): @staticmethod def validate_rbac_ruletype(types): """Validate RBAC rule types.""" + warnings.warn("RBAC ruletypes have changed to an enumeration.", + DeprecationWarning) return rbacrule.validate_ruletype(types) @staticmethod diff --git a/setools/rbacrulequery.py b/setools/rbacrulequery.py index 2a8e260..a4efd4d 100644 --- a/setools/rbacrulequery.py +++ b/setools/rbacrulequery.py @@ -21,6 +21,7 @@ import re from . import mixins, query from .descriptors import CriteriaDescriptor, CriteriaSetDescriptor +from .policyrep import RBACRuletype from .policyrep.exception import InvalidType, RuleUseError from .util import match_indirect_regex @@ -55,7 +56,7 @@ class RBACRuleQuery(mixins.MatchObjClass, query.PolicyQuery): be used on the default role. """ - ruletype = CriteriaSetDescriptor(lookup_function="validate_rbac_ruletype") + ruletype = CriteriaSetDescriptor(enum_class=RBACRuletype) source = CriteriaDescriptor("source_regex", "lookup_role") source_regex = False source_indirect = True diff --git a/setoolsgui/rbacrulemodel.py b/setoolsgui/rbacrulemodel.py index 47680ec..0217269 100644 --- a/setoolsgui/rbacrulemodel.py +++ b/setoolsgui/rbacrulemodel.py @@ -36,7 +36,7 @@ class RBACRuleTableModel(SEToolsTableModel): if role == Qt.DisplayRole: if col == 0: - return rule.ruletype + return rule.ruletype.name elif col == 1: return str(rule.source) elif col == 2: diff --git a/tests/diff.py b/tests/diff.py index 64c4195..948c8f5 100644 --- a/tests/diff.py +++ b/tests/diff.py @@ -20,6 +20,7 @@ import unittest from socket import IPPROTO_TCP, IPPROTO_UDP from setools import SELinuxPolicy, PolicyDifference +from setools import RBACRuletype as RRT from setools import TERuletype as TRT from .mixins import ValidateRule @@ -790,12 +791,12 @@ class PolicyDifferenceTest(ValidateRule, unittest.TestCase): self.assertEqual(2, len(rules)) # added rule with existing roles - self.assertEqual("allow", rules[0].ruletype) + self.assertEqual(RRT.allow, rules[0].ruletype) self.assertEqual("added_role", rules[0].source) self.assertEqual("system", rules[0].target) # added rule with new roles - self.assertEqual("allow", rules[1].ruletype) + self.assertEqual(RRT.allow, rules[1].ruletype) self.assertEqual("added_rule_source_r", rules[1].source) self.assertEqual("added_rule_target_r", rules[1].target) @@ -805,12 +806,12 @@ class PolicyDifferenceTest(ValidateRule, unittest.TestCase): self.assertEqual(2, len(rules)) # removed rule with removed role - self.assertEqual("allow", rules[0].ruletype) + self.assertEqual(RRT.allow, rules[0].ruletype) self.assertEqual("removed_role", rules[0].source) self.assertEqual("system", rules[0].target) # removed rule with existing roles - self.assertEqual("allow", rules[1].ruletype) + self.assertEqual(RRT.allow, rules[1].ruletype) self.assertEqual("removed_rule_source_r", rules[1].source) self.assertEqual("removed_rule_target_r", rules[1].target) @@ -823,11 +824,11 @@ class PolicyDifferenceTest(ValidateRule, unittest.TestCase): self.assertEqual(2, len(rules)) # added rule with new role - self.validate_rule(rules[0], "role_transition", "added_role", "system", "infoflow4", + self.validate_rule(rules[0], RRT.role_transition, "added_role", "system", "infoflow4", "system") # added rule with existing roles - self.validate_rule(rules[1], "role_transition", "role_tr_added_rule_source", + self.validate_rule(rules[1], RRT.role_transition, "role_tr_added_rule_source", "role_tr_added_rule_target", "infoflow6", "system") def test_removed_role_transition_rules(self): @@ -836,11 +837,11 @@ class PolicyDifferenceTest(ValidateRule, unittest.TestCase): self.assertEqual(2, len(rules)) # removed rule with new role - self.validate_rule(rules[0], "role_transition", "removed_role", "system", "infoflow4", + self.validate_rule(rules[0], RRT.role_transition, "removed_role", "system", "infoflow4", "system") # removed rule with existing roles - self.validate_rule(rules[1], "role_transition", "role_tr_removed_rule_source", + self.validate_rule(rules[1], RRT.role_transition, "role_tr_removed_rule_source", "role_tr_removed_rule_target", "infoflow5", "system") def test_modified_role_transition_rules(self): @@ -849,7 +850,7 @@ class PolicyDifferenceTest(ValidateRule, unittest.TestCase): self.assertEqual(1, len(l)) rule, added_default, removed_default = l[0] - self.assertEqual("role_transition", rule.ruletype) + self.assertEqual(RRT.role_transition, rule.ruletype) self.assertEqual("role_tr_matched_source", rule.source) self.assertEqual("role_tr_matched_target", rule.target) self.assertEqual("infoflow3", rule.tclass) diff --git a/tests/policyrep/rbacrule.py b/tests/policyrep/rbacrule.py index 2135cc1..5ed684d 100644 --- a/tests/policyrep/rbacrule.py +++ b/tests/policyrep/rbacrule.py @@ -23,7 +23,7 @@ except ImportError: from mock import Mock, patch from setools.policyrep.qpol import qpol_policy_t, qpol_role_allow_t, qpol_role_trans_t -from setools.policyrep.rbacrule import rbac_rule_factory, validate_ruletype +from setools.policyrep.rbacrule import rbac_rule_factory, validate_ruletype, RBACRuletype from setools.policyrep.exception import InvalidRBACRuleType, RuleNotConditional, RuleUseError @@ -32,7 +32,7 @@ class RoleAllowTest(unittest.TestCase): def mock_avrule_factory(self, source, target): mock_rule = Mock(qpol_role_allow_t) - mock_rule.rule_type.return_value = "allow" + mock_rule.rule_type.return_value = RBACRuletype.allow mock_rule.source_role.return_value = source mock_rule.target_role.return_value = target @@ -46,6 +46,7 @@ class RoleAllowTest(unittest.TestCase): with self.assertRaises(TypeError): rbac_rule_factory(self.p, "INVALID") + @unittest.skip("RBAC ruletype changed to an enumeration.") def test_001_validate_ruletype(self): """RoleAllow valid rule types.""" # no return value means a return of None @@ -59,7 +60,7 @@ class RoleAllowTest(unittest.TestCase): def test_010_ruletype(self): """RoleAllow rule type""" rule = self.mock_avrule_factory("a", "b") - self.assertEqual("allow", rule.ruletype) + self.assertEqual(RBACRuletype.allow, rule.ruletype) def test_020_source_role(self): """RoleAllow source role""" @@ -102,7 +103,7 @@ class RoleTransitionTest(unittest.TestCase): def mock_roletrans_factory(self, source, target, tclass, default): mock_rule = Mock(qpol_role_trans_t) - mock_rule.rule_type.return_value = "role_transition" + mock_rule.rule_type.return_value = RBACRuletype.role_transition mock_rule.source_role.return_value = source mock_rule.target_type.return_value = target mock_rule.object_class.return_value = tclass @@ -120,7 +121,7 @@ class RoleTransitionTest(unittest.TestCase): def test_001_validate_ruletype(self): """RoleTransition valid rule types.""" - self.assertEqual("role_transition", validate_ruletype("role_transition")) + self.assertEqual(RBACRuletype.role_transition, validate_ruletype("role_transition")) def test_002_validate_ruletype_invalid(self): """RoleTransition valid rule types.""" @@ -130,7 +131,7 @@ class RoleTransitionTest(unittest.TestCase): def test_010_ruletype(self): """RoleTransition rule type""" rule = self.mock_roletrans_factory("a", "b", "c", "d") - self.assertEqual("role_transition", rule.ruletype) + self.assertEqual(RBACRuletype.role_transition, rule.ruletype) def test_020_source_role(self): """RoleTransition source role""" diff --git a/tests/rbacrulequery.py b/tests/rbacrulequery.py index a89d20a..842d174 100644 --- a/tests/rbacrulequery.py +++ b/tests/rbacrulequery.py @@ -20,6 +20,7 @@ import unittest from setools import SELinuxPolicy, RBACRuleQuery +from setools import RBACRuletype as RRT from setools.policyrep.exception import RuleUseError, RuleNotConditional from . import mixins @@ -35,7 +36,7 @@ class RBACRuleQueryTest(mixins.ValidateRule, unittest.TestCase): def validate_allow(self, rule, source, target): """Validate a role allow rule.""" - self.assertEqual("allow", rule.ruletype) + self.assertEqual(RRT.allow, rule.ruletype) self.assertEqual(source, rule.source) self.assertEqual(target, rule.target) self.assertRaises(RuleUseError, getattr, rule, "tclass") @@ -61,7 +62,7 @@ class RBACRuleQueryTest(mixins.ValidateRule, unittest.TestCase): self.assertEqual(len(r), 2) self.validate_allow(r[0], "test1s", "test1t") - self.validate_rule(r[1], "role_transition", "test1s", "system", "infoflow", "test1t") + self.validate_rule(r[1], RRT.role_transition, "test1s", "system", "infoflow", "test1t") def test_002_source_direct_regex(self): """RBAC rule query with regex, direct, source match.""" @@ -96,7 +97,7 @@ class RBACRuleQueryTest(mixins.ValidateRule, unittest.TestCase): r = sorted(q.results()) self.assertEqual(len(r), 1) - self.validate_rule(r[0], "role_transition", "test12s", "test12t", "infoflow", "test12d") + self.validate_rule(r[0], RRT.role_transition, "test12s", "test12t", "infoflow", "test12d") @unittest.skip("Setting tclass to a string is no longer supported.") def test_020_class(self): @@ -105,7 +106,7 @@ class RBACRuleQueryTest(mixins.ValidateRule, unittest.TestCase): r = sorted(q.results()) self.assertEqual(len(r), 1) - self.validate_rule(r[0], "role_transition", "test20", "system", "infoflow2", "test20d2") + self.validate_rule(r[0], RRT.role_transition, "test20", "system", "infoflow2", "test20d2") def test_021_class_list(self): """RBAC rule query with object class list match.""" @@ -114,8 +115,8 @@ class RBACRuleQueryTest(mixins.ValidateRule, unittest.TestCase): r = sorted(q.results()) self.assertEqual(len(r), 2) - self.validate_rule(r[0], "role_transition", "test21", "system", "infoflow3", "test21d3") - self.validate_rule(r[1], "role_transition", "test21", "system", "infoflow4", "test21d2") + self.validate_rule(r[0], RRT.role_transition, "test21", "system", "infoflow3", "test21d3") + self.validate_rule(r[1], RRT.role_transition, "test21", "system", "infoflow4", "test21d2") def test_022_class_regex(self): """RBAC rule query with object class regex match.""" @@ -123,8 +124,8 @@ class RBACRuleQueryTest(mixins.ValidateRule, unittest.TestCase): r = sorted(q.results()) self.assertEqual(len(r), 2) - self.validate_rule(r[0], "role_transition", "test22", "system", "infoflow5", "test22d2") - self.validate_rule(r[1], "role_transition", "test22", "system", "infoflow6", "test22d3") + self.validate_rule(r[0], RRT.role_transition, "test22", "system", "infoflow5", "test22d2") + self.validate_rule(r[1], RRT.role_transition, "test22", "system", "infoflow6", "test22d3") def test_030_default(self): """RBAC rule query with exact default match.""" @@ -133,7 +134,7 @@ class RBACRuleQueryTest(mixins.ValidateRule, unittest.TestCase): r = sorted(q.results()) self.assertEqual(len(r), 1) - self.validate_rule(r[0], "role_transition", "test30s", "system", "infoflow", "test30d") + self.validate_rule(r[0], RRT.role_transition, "test30s", "system", "infoflow", "test30d") def test_031_default_regex(self): """RBAC rule query with regex default match.""" @@ -142,16 +143,16 @@ class RBACRuleQueryTest(mixins.ValidateRule, unittest.TestCase): r = sorted(q.results()) self.assertEqual(len(r), 2) - self.validate_rule(r[0], "role_transition", "test31s", "system", "infoflow7", "test31d3") - self.validate_rule(r[1], "role_transition", "test31s", "system", "process", "test31d2") + self.validate_rule(r[0], RRT.role_transition, "test31s", "system", "infoflow7", "test31d3") + self.validate_rule(r[1], RRT.role_transition, "test31s", "system", "process", "test31d2") def test_040_ruletype(self): """RBAC rule query with rule type.""" - q = RBACRuleQuery(self.p, ruletype=["allow"]) + q = RBACRuleQuery(self.p, ruletype=[RRT.allow]) num = 0 for num, r in enumerate(sorted(q.results()), start=1): - self.assertEqual(r.ruletype, "allow") + self.assertEqual(r.ruletype, RRT.allow) # this will have to be updated as number of # role allows change in the test policy