Implement an enumeration for RBAC rule type.

This commit is contained in:
Chris PeBenito 2016-09-03 16:19:52 -04:00
parent f3fb462c88
commit a441a92937
10 changed files with 59 additions and 40 deletions

View File

@ -69,10 +69,10 @@ rtypes.add_argument("--type_member", action="append_const",
help="Search type_member rules.") help="Search type_member rules.")
rbacrtypes = parser.add_argument_group("RBAC Rule Types") rbacrtypes = parser.add_argument_group("RBAC Rule Types")
rbacrtypes.add_argument("--role_allow", action="append_const", rbacrtypes.add_argument("--role_allow", action="append_const",
const="allow", dest="rbacrtypes", const=setools.RBACRuletype.allow, dest="rbacrtypes",
help="Search role allow rules.") help="Search role allow rules.")
rbacrtypes.add_argument("--role_trans", action="append_const", 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.") help="Search role_transition rules.")
mlsrtypes = parser.add_argument_group("MLS Rule Types") mlsrtypes = parser.add_argument_group("MLS Rule Types")

View File

@ -18,6 +18,7 @@
# #
from collections import defaultdict, namedtuple from collections import defaultdict, namedtuple
from ..policyrep import RBACRuletype
from .descriptors import DiffResultDescriptor from .descriptors import DiffResultDescriptor
from .difference import Difference, SymbolWrapper, Wrapper from .difference import Difference, SymbolWrapper, Wrapper
@ -54,8 +55,8 @@ class RBACRulesDifference(Difference):
self._create_rbac_rule_lists() self._create_rbac_rule_lists()
self.added_role_allows, self.removed_role_allows, _ = self._set_diff( self.added_role_allows, self.removed_role_allows, _ = self._set_diff(
self._expand_generator(self._left_rbac_rules["allow"], RoleAllowWrapper), self._expand_generator(self._left_rbac_rules[RBACRuletype.allow], RoleAllowWrapper),
self._expand_generator(self._right_rbac_rules["allow"], RoleAllowWrapper)) self._expand_generator(self._right_rbac_rules[RBACRuletype.allow], RoleAllowWrapper))
def diff_role_transitions(self): def diff_role_transitions(self):
"""Generate the difference in role_transition rules between the policies.""" """Generate the difference in role_transition rules between the policies."""
@ -68,8 +69,9 @@ class RBACRulesDifference(Difference):
self._create_rbac_rule_lists() self._create_rbac_rule_lists()
added, removed, matched = self._set_diff( added, removed, matched = self._set_diff(
self._expand_generator(self._left_rbac_rules["role_transition"], RoleTransitionWrapper), self._expand_generator(self._left_rbac_rules[RBACRuletype.role_transition],
self._expand_generator(self._right_rbac_rules["role_transition"], RoleTransitionWrapper),
self._expand_generator(self._right_rbac_rules[RBACRuletype.role_transition],
RoleTransitionWrapper)) RoleTransitionWrapper))
modified = [] modified = []

View File

@ -23,6 +23,7 @@
from . import exception from . import exception
from .netcontext import PortconProtocol, PortconRange from .netcontext import PortconProtocol, PortconRange
from .rbacrule import RBACRuletype
from .selinuxpolicy import SELinuxPolicy from .selinuxpolicy import SELinuxPolicy
from .terule import IoctlSet, TERuletype from .terule import IoctlSet, TERuletype
from .xencontext import IomemconRange, IoportconRange from .xencontext import IomemconRange, IoportconRange

View File

@ -1,4 +1,5 @@
# Copyright 2014, 2016, Tresys Technology, LLC # Copyright 2014, 2016, Tresys Technology, LLC
# Copyright 2016, Chris PeBenito <pebenito@ieee.org>
# #
# This file is part of SETools. # This file is part of SETools.
# #
@ -23,6 +24,7 @@ from . import qpol
from . import rule from . import rule
from . import role from . import role
from . import typeattr from . import typeattr
from .util import PolicyEnum
def rbac_rule_factory(policy, name): def rbac_rule_factory(policy, name):
@ -62,10 +64,18 @@ def expanded_rbac_rule_factory(original, source, target):
def validate_ruletype(t): def validate_ruletype(t):
"""Validate RBAC rule types.""" """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)) 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): class RoleAllow(rule.PolicyRule):
@ -78,7 +88,7 @@ class RoleAllow(rule.PolicyRule):
def __hash__(self): def __hash__(self):
return hash("{0.ruletype}|{0.source}|{0.target}".format(self)) return hash("{0.ruletype}|{0.source}|{0.target}".format(self))
ruletype = "allow" ruletype = RBACRuletype.allow
@property @property
def source(self): def source(self):
@ -113,7 +123,7 @@ class RoleTransition(rule.PolicyRule):
def __str__(self): def __str__(self):
return "{0.ruletype} {0.source} {0.target}:{0.tclass} {0.default};".format(self) return "{0.ruletype} {0.source} {0.target}:{0.tclass} {0.default};".format(self)
ruletype = "role_transition" ruletype = RBACRuletype.role_transition
@property @property
def source(self): def source(self):

View File

@ -608,6 +608,8 @@ class SELinuxPolicy(object):
@staticmethod @staticmethod
def validate_rbac_ruletype(types): def validate_rbac_ruletype(types):
"""Validate RBAC rule types.""" """Validate RBAC rule types."""
warnings.warn("RBAC ruletypes have changed to an enumeration.",
DeprecationWarning)
return rbacrule.validate_ruletype(types) return rbacrule.validate_ruletype(types)
@staticmethod @staticmethod

View File

@ -21,6 +21,7 @@ import re
from . import mixins, query from . import mixins, query
from .descriptors import CriteriaDescriptor, CriteriaSetDescriptor from .descriptors import CriteriaDescriptor, CriteriaSetDescriptor
from .policyrep import RBACRuletype
from .policyrep.exception import InvalidType, RuleUseError from .policyrep.exception import InvalidType, RuleUseError
from .util import match_indirect_regex from .util import match_indirect_regex
@ -55,7 +56,7 @@ class RBACRuleQuery(mixins.MatchObjClass, query.PolicyQuery):
be used on the default role. 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 = CriteriaDescriptor("source_regex", "lookup_role")
source_regex = False source_regex = False
source_indirect = True source_indirect = True

View File

@ -36,7 +36,7 @@ class RBACRuleTableModel(SEToolsTableModel):
if role == Qt.DisplayRole: if role == Qt.DisplayRole:
if col == 0: if col == 0:
return rule.ruletype return rule.ruletype.name
elif col == 1: elif col == 1:
return str(rule.source) return str(rule.source)
elif col == 2: elif col == 2:

View File

@ -20,6 +20,7 @@ import unittest
from socket import IPPROTO_TCP, IPPROTO_UDP from socket import IPPROTO_TCP, IPPROTO_UDP
from setools import SELinuxPolicy, PolicyDifference from setools import SELinuxPolicy, PolicyDifference
from setools import RBACRuletype as RRT
from setools import TERuletype as TRT from setools import TERuletype as TRT
from .mixins import ValidateRule from .mixins import ValidateRule
@ -790,12 +791,12 @@ class PolicyDifferenceTest(ValidateRule, unittest.TestCase):
self.assertEqual(2, len(rules)) self.assertEqual(2, len(rules))
# added rule with existing roles # 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("added_role", rules[0].source)
self.assertEqual("system", rules[0].target) self.assertEqual("system", rules[0].target)
# added rule with new roles # 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_source_r", rules[1].source)
self.assertEqual("added_rule_target_r", rules[1].target) self.assertEqual("added_rule_target_r", rules[1].target)
@ -805,12 +806,12 @@ class PolicyDifferenceTest(ValidateRule, unittest.TestCase):
self.assertEqual(2, len(rules)) self.assertEqual(2, len(rules))
# removed rule with removed role # 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("removed_role", rules[0].source)
self.assertEqual("system", rules[0].target) self.assertEqual("system", rules[0].target)
# removed rule with existing roles # 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_source_r", rules[1].source)
self.assertEqual("removed_rule_target_r", rules[1].target) self.assertEqual("removed_rule_target_r", rules[1].target)
@ -823,11 +824,11 @@ class PolicyDifferenceTest(ValidateRule, unittest.TestCase):
self.assertEqual(2, len(rules)) self.assertEqual(2, len(rules))
# added rule with new role # 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") "system")
# added rule with existing roles # 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") "role_tr_added_rule_target", "infoflow6", "system")
def test_removed_role_transition_rules(self): def test_removed_role_transition_rules(self):
@ -836,11 +837,11 @@ class PolicyDifferenceTest(ValidateRule, unittest.TestCase):
self.assertEqual(2, len(rules)) self.assertEqual(2, len(rules))
# removed rule with new role # 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") "system")
# removed rule with existing roles # 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") "role_tr_removed_rule_target", "infoflow5", "system")
def test_modified_role_transition_rules(self): def test_modified_role_transition_rules(self):
@ -849,7 +850,7 @@ class PolicyDifferenceTest(ValidateRule, unittest.TestCase):
self.assertEqual(1, len(l)) self.assertEqual(1, len(l))
rule, added_default, removed_default = l[0] 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_source", rule.source)
self.assertEqual("role_tr_matched_target", rule.target) self.assertEqual("role_tr_matched_target", rule.target)
self.assertEqual("infoflow3", rule.tclass) self.assertEqual("infoflow3", rule.tclass)

View File

@ -23,7 +23,7 @@ except ImportError:
from mock import Mock, patch from mock import Mock, patch
from setools.policyrep.qpol import qpol_policy_t, qpol_role_allow_t, qpol_role_trans_t 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 from setools.policyrep.exception import InvalidRBACRuleType, RuleNotConditional, RuleUseError
@ -32,7 +32,7 @@ class RoleAllowTest(unittest.TestCase):
def mock_avrule_factory(self, source, target): def mock_avrule_factory(self, source, target):
mock_rule = Mock(qpol_role_allow_t) 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.source_role.return_value = source
mock_rule.target_role.return_value = target mock_rule.target_role.return_value = target
@ -46,6 +46,7 @@ class RoleAllowTest(unittest.TestCase):
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
rbac_rule_factory(self.p, "INVALID") rbac_rule_factory(self.p, "INVALID")
@unittest.skip("RBAC ruletype changed to an enumeration.")
def test_001_validate_ruletype(self): def test_001_validate_ruletype(self):
"""RoleAllow valid rule types.""" """RoleAllow valid rule types."""
# no return value means a return of None # no return value means a return of None
@ -59,7 +60,7 @@ class RoleAllowTest(unittest.TestCase):
def test_010_ruletype(self): def test_010_ruletype(self):
"""RoleAllow rule type""" """RoleAllow rule type"""
rule = self.mock_avrule_factory("a", "b") rule = self.mock_avrule_factory("a", "b")
self.assertEqual("allow", rule.ruletype) self.assertEqual(RBACRuletype.allow, rule.ruletype)
def test_020_source_role(self): def test_020_source_role(self):
"""RoleAllow source role""" """RoleAllow source role"""
@ -102,7 +103,7 @@ class RoleTransitionTest(unittest.TestCase):
def mock_roletrans_factory(self, source, target, tclass, default): def mock_roletrans_factory(self, source, target, tclass, default):
mock_rule = Mock(qpol_role_trans_t) 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.source_role.return_value = source
mock_rule.target_type.return_value = target mock_rule.target_type.return_value = target
mock_rule.object_class.return_value = tclass mock_rule.object_class.return_value = tclass
@ -120,7 +121,7 @@ class RoleTransitionTest(unittest.TestCase):
def test_001_validate_ruletype(self): def test_001_validate_ruletype(self):
"""RoleTransition valid rule types.""" """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): def test_002_validate_ruletype_invalid(self):
"""RoleTransition valid rule types.""" """RoleTransition valid rule types."""
@ -130,7 +131,7 @@ class RoleTransitionTest(unittest.TestCase):
def test_010_ruletype(self): def test_010_ruletype(self):
"""RoleTransition rule type""" """RoleTransition rule type"""
rule = self.mock_roletrans_factory("a", "b", "c", "d") 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): def test_020_source_role(self):
"""RoleTransition source role""" """RoleTransition source role"""

View File

@ -20,6 +20,7 @@
import unittest import unittest
from setools import SELinuxPolicy, RBACRuleQuery from setools import SELinuxPolicy, RBACRuleQuery
from setools import RBACRuletype as RRT
from setools.policyrep.exception import RuleUseError, RuleNotConditional from setools.policyrep.exception import RuleUseError, RuleNotConditional
from . import mixins from . import mixins
@ -35,7 +36,7 @@ class RBACRuleQueryTest(mixins.ValidateRule, unittest.TestCase):
def validate_allow(self, rule, source, target): def validate_allow(self, rule, source, target):
"""Validate a role allow rule.""" """Validate a role allow rule."""
self.assertEqual("allow", rule.ruletype) self.assertEqual(RRT.allow, rule.ruletype)
self.assertEqual(source, rule.source) self.assertEqual(source, rule.source)
self.assertEqual(target, rule.target) self.assertEqual(target, rule.target)
self.assertRaises(RuleUseError, getattr, rule, "tclass") self.assertRaises(RuleUseError, getattr, rule, "tclass")
@ -61,7 +62,7 @@ class RBACRuleQueryTest(mixins.ValidateRule, unittest.TestCase):
self.assertEqual(len(r), 2) self.assertEqual(len(r), 2)
self.validate_allow(r[0], "test1s", "test1t") 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): def test_002_source_direct_regex(self):
"""RBAC rule query with regex, direct, source match.""" """RBAC rule query with regex, direct, source match."""
@ -96,7 +97,7 @@ class RBACRuleQueryTest(mixins.ValidateRule, unittest.TestCase):
r = sorted(q.results()) r = sorted(q.results())
self.assertEqual(len(r), 1) 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.") @unittest.skip("Setting tclass to a string is no longer supported.")
def test_020_class(self): def test_020_class(self):
@ -105,7 +106,7 @@ class RBACRuleQueryTest(mixins.ValidateRule, unittest.TestCase):
r = sorted(q.results()) r = sorted(q.results())
self.assertEqual(len(r), 1) 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): def test_021_class_list(self):
"""RBAC rule query with object class list match.""" """RBAC rule query with object class list match."""
@ -114,8 +115,8 @@ class RBACRuleQueryTest(mixins.ValidateRule, unittest.TestCase):
r = sorted(q.results()) r = sorted(q.results())
self.assertEqual(len(r), 2) self.assertEqual(len(r), 2)
self.validate_rule(r[0], "role_transition", "test21", "system", "infoflow3", "test21d3") self.validate_rule(r[0], RRT.role_transition, "test21", "system", "infoflow3", "test21d3")
self.validate_rule(r[1], "role_transition", "test21", "system", "infoflow4", "test21d2") self.validate_rule(r[1], RRT.role_transition, "test21", "system", "infoflow4", "test21d2")
def test_022_class_regex(self): def test_022_class_regex(self):
"""RBAC rule query with object class regex match.""" """RBAC rule query with object class regex match."""
@ -123,8 +124,8 @@ class RBACRuleQueryTest(mixins.ValidateRule, unittest.TestCase):
r = sorted(q.results()) r = sorted(q.results())
self.assertEqual(len(r), 2) self.assertEqual(len(r), 2)
self.validate_rule(r[0], "role_transition", "test22", "system", "infoflow5", "test22d2") self.validate_rule(r[0], RRT.role_transition, "test22", "system", "infoflow5", "test22d2")
self.validate_rule(r[1], "role_transition", "test22", "system", "infoflow6", "test22d3") self.validate_rule(r[1], RRT.role_transition, "test22", "system", "infoflow6", "test22d3")
def test_030_default(self): def test_030_default(self):
"""RBAC rule query with exact default match.""" """RBAC rule query with exact default match."""
@ -133,7 +134,7 @@ class RBACRuleQueryTest(mixins.ValidateRule, unittest.TestCase):
r = sorted(q.results()) r = sorted(q.results())
self.assertEqual(len(r), 1) 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): def test_031_default_regex(self):
"""RBAC rule query with regex default match.""" """RBAC rule query with regex default match."""
@ -142,16 +143,16 @@ class RBACRuleQueryTest(mixins.ValidateRule, unittest.TestCase):
r = sorted(q.results()) r = sorted(q.results())
self.assertEqual(len(r), 2) self.assertEqual(len(r), 2)
self.validate_rule(r[0], "role_transition", "test31s", "system", "infoflow7", "test31d3") self.validate_rule(r[0], RRT.role_transition, "test31s", "system", "infoflow7", "test31d3")
self.validate_rule(r[1], "role_transition", "test31s", "system", "process", "test31d2") self.validate_rule(r[1], RRT.role_transition, "test31s", "system", "process", "test31d2")
def test_040_ruletype(self): def test_040_ruletype(self):
"""RBAC rule query with rule type.""" """RBAC rule query with rule type."""
q = RBACRuleQuery(self.p, ruletype=["allow"]) q = RBACRuleQuery(self.p, ruletype=[RRT.allow])
num = 0 num = 0
for num, r in enumerate(sorted(q.results()), start=1): 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 # this will have to be updated as number of
# role allows change in the test policy # role allows change in the test policy