Revise rule type validators to operate on single object, not collections.

* Return the parameter on success so it works like a lookup function too
* Remove RuletypeDescriptor and change over to CriteriaSetDescriptor
This commit is contained in:
Chris PeBenito 2016-02-01 09:00:54 -05:00
parent 0bd9d931c4
commit eafaad4dde
15 changed files with 48 additions and 83 deletions

View File

@ -20,7 +20,7 @@ import logging
import re import re
from . import mixins, query from . import mixins, query
from .descriptors import CriteriaDescriptor, CriteriaSetDescriptor, RuletypeDescriptor from .descriptors import CriteriaDescriptor, CriteriaSetDescriptor
from .policyrep.exception import ConstraintUseError from .policyrep.exception import ConstraintUseError
@ -62,7 +62,7 @@ class ConstraintQuery(mixins.MatchObjClass, mixins.MatchPermission, query.Policy
be used on the user. be used on the user.
""" """
ruletype = RuletypeDescriptor("validate_constraint_ruletype") ruletype = CriteriaSetDescriptor(lookup_function="validate_constraint_ruletype")
user = CriteriaDescriptor("user_regex", "lookup_user") user = CriteriaDescriptor("user_regex", "lookup_user")
user_regex = False user_regex = False
role = CriteriaDescriptor("role_regex", "lookup_role") role = CriteriaDescriptor("role_regex", "lookup_role")

View File

@ -106,44 +106,6 @@ class CriteriaSetDescriptor(CriteriaDescriptor):
self.instances[obj] = set(value) self.instances[obj] = set(value)
class RuletypeDescriptor(object):
"""
Descriptor for a list of rule types.
Parameters:
validator The name of the SELinuxPolicy ruletype
validator function, e.g. validate_te_ruletype
default_value The default value of the criteria. The default
is None.
Read-only instance attribute use (obj parameter):
policy The instance of SELinuxPolicy
"""
def __init__(self, validator):
self.validator = validator
# use weak references so instances can be
# garbage collected, rather than unnecessarily
# kept around due to this descriptor.
self.instances = WeakKeyDictionary()
def __get__(self, obj, objtype=None):
if obj is None:
return self
return self.instances.setdefault(obj, None)
def __set__(self, obj, value):
if value:
validate = getattr(obj.policy, self.validator)
validate(value)
self.instances[obj] = value
else:
self.instances[obj] = None
# #
# NetworkX Graph Descriptors # NetworkX Graph Descriptors
# #

View File

@ -20,7 +20,7 @@ import logging
import re import re
from . import contextquery from . import contextquery
from .descriptors import CriteriaDescriptor, CriteriaSetDescriptor, RuletypeDescriptor from .descriptors import CriteriaDescriptor, CriteriaSetDescriptor
class FSUseQuery(contextquery.ContextQuery): class FSUseQuery(contextquery.ContextQuery):
@ -56,7 +56,7 @@ class FSUseQuery(contextquery.ContextQuery):
No effect if not using set operations. No effect if not using set operations.
""" """
ruletype = RuletypeDescriptor("validate_fs_use_ruletype") ruletype = CriteriaSetDescriptor(lookup_function="validate_fs_use_ruletype")
fs = CriteriaDescriptor("fs_regex") fs = CriteriaDescriptor("fs_regex")
fs_regex = False fs_regex = False

View File

@ -19,7 +19,7 @@
import logging import logging
from . import mixins, query from . import mixins, query
from .descriptors import CriteriaDescriptor, CriteriaSetDescriptor, RuletypeDescriptor from .descriptors import CriteriaDescriptor, CriteriaSetDescriptor
class MLSRuleQuery(mixins.MatchObjClass, query.PolicyQuery): class MLSRuleQuery(mixins.MatchObjClass, query.PolicyQuery):
@ -43,7 +43,7 @@ class MLSRuleQuery(mixins.MatchObjClass, query.PolicyQuery):
matching the rule's object class. matching the rule's object class.
""" """
ruletype = RuletypeDescriptor("validate_mls_ruletype") ruletype = CriteriaSetDescriptor(lookup_function="validate_mls_ruletype")
source = CriteriaDescriptor("source_regex", "lookup_type_or_attr") source = CriteriaDescriptor("source_regex", "lookup_type_or_attr")
source_regex = False source_regex = False
target = CriteriaDescriptor("target_regex", "lookup_type_or_attr") target = CriteriaDescriptor("target_regex", "lookup_type_or_attr")

View File

@ -505,7 +505,7 @@ class SELinuxPolicy(object):
@staticmethod @staticmethod
def validate_constraint_ruletype(types): def validate_constraint_ruletype(types):
"""Validate constraint types.""" """Validate constraint types."""
constraint.validate_ruletype(types) return constraint.validate_ruletype(types)
@staticmethod @staticmethod
def validate_default_ruletype(types): def validate_default_ruletype(types):
@ -525,22 +525,22 @@ class SELinuxPolicy(object):
@staticmethod @staticmethod
def validate_fs_use_ruletype(types): def validate_fs_use_ruletype(types):
"""Validate fs_use_* rule types.""" """Validate fs_use_* rule types."""
fscontext.validate_ruletype(types) return fscontext.validate_ruletype(types)
@staticmethod @staticmethod
def validate_mls_ruletype(types): def validate_mls_ruletype(types):
"""Validate MLS rule types.""" """Validate MLS rule types."""
mlsrule.validate_ruletype(types) return mlsrule.validate_ruletype(types)
@staticmethod @staticmethod
def validate_rbac_ruletype(types): def validate_rbac_ruletype(types):
"""Validate RBAC rule types.""" """Validate RBAC rule types."""
rbacrule.validate_ruletype(types) return rbacrule.validate_ruletype(types)
@staticmethod @staticmethod
def validate_te_ruletype(types): def validate_te_ruletype(types):
"""Validate type enforcement rule types.""" """Validate type enforcement rule types."""
terule.validate_ruletype(types) return terule.validate_ruletype(types)
# #
# Constraints generators # Constraints generators

View File

@ -38,11 +38,12 @@ def _is_mls(policy, sym):
return False return False
def validate_ruletype(types): def validate_ruletype(t):
"""Validate constraint rule types.""" """Validate constraint rule types."""
for t in types: if t not in ["constrain", "mlsconstrain", "validatetrans", "mlsvalidatetrans"]:
if t not in ["constrain", "mlsconstrain", "validatetrans", "mlsvalidatetrans"]: raise exception.InvalidConstraintType("{0} is not a valid constraint type.".format(t))
raise exception.InvalidConstraintType("{0} is not a valid constraint type.".format(t))
return t
def constraint_factory(policy, sym): def constraint_factory(policy, sym):

View File

@ -24,11 +24,12 @@ from . import symbol
from . import context from . import context
def validate_ruletype(types): def validate_ruletype(t):
"""Validate fs_use_* rule types.""" """Validate fs_use_* rule types."""
for t in types: if t not in ["fs_use_xattr", "fs_use_trans", "fs_use_task"]:
if t not in ["fs_use_xattr", "fs_use_trans", "fs_use_task"]: raise exception.InvalidFSUseType("{0} is not a valid fs_use_* type.".format(t))
raise exception.InvalidConstraintType("{0} is not a valid fs_use_* type.".format(t))
return t
def fs_use_factory(policy, name): def fs_use_factory(policy, name):

View File

@ -55,11 +55,12 @@ def expanded_mls_rule_factory(original, source, target):
return rule return rule
def validate_ruletype(types): def validate_ruletype(t):
"""Validate MLS rule types.""" """Validate MLS rule types."""
for t in types: if t not in ["range_transition"]:
if t not in ["range_transition"]: raise exception.InvalidMLSRuleType("{0} is not a valid MLS rule type.".format(t))
raise exception.InvalidMLSRuleType("{0} is not a valid MLS rule type.".format(t))
return t
class MLSRule(rule.PolicyRule): class MLSRule(rule.PolicyRule):

View File

@ -60,11 +60,12 @@ def expanded_rbac_rule_factory(original, source, target):
return rule return rule
def validate_ruletype(types): def validate_ruletype(t):
"""Validate RBAC rule types.""" """Validate RBAC rule types."""
for t in types: if t not in ["allow", "role_transition"]:
if t not in ["allow", "role_transition"]: 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 RoleAllow(rule.PolicyRule): class RoleAllow(rule.PolicyRule):

View File

@ -60,12 +60,13 @@ def expanded_te_rule_factory(original, source, target):
return rule return rule
def validate_ruletype(types): def validate_ruletype(t):
"""Validate TE Rule types.""" """Validate TE Rule types."""
for t in types: if t not in ["allow", "auditallow", "dontaudit", "neverallow",
if t not in ["allow", "auditallow", "dontaudit", "neverallow", "type_transition", "type_member", "type_change"]:
"type_transition", "type_member", "type_change"]: raise exception.InvalidTERuleType("{0} is not a valid TE rule type.".format(t))
raise exception.InvalidTERuleType("{0} is not a valid TE rule type.".format(t))
return t
class BaseTERule(rule.PolicyRule): class BaseTERule(rule.PolicyRule):

View File

@ -20,7 +20,7 @@ import logging
import re import re
from . import mixins, query from . import mixins, query
from .descriptors import CriteriaDescriptor, CriteriaSetDescriptor, RuletypeDescriptor from .descriptors import CriteriaDescriptor, CriteriaSetDescriptor
from .policyrep.exception import InvalidType, RuleUseError from .policyrep.exception import InvalidType, RuleUseError
@ -54,7 +54,7 @@ class RBACRuleQuery(mixins.MatchObjClass, query.PolicyQuery):
be used on the default role. be used on the default role.
""" """
ruletype = RuletypeDescriptor("validate_rbac_ruletype") ruletype = CriteriaSetDescriptor(lookup_function="validate_rbac_ruletype")
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

@ -20,7 +20,7 @@ import logging
import re import re
from . import mixins, query from . import mixins, query
from .descriptors import CriteriaDescriptor, CriteriaSetDescriptor, RuletypeDescriptor from .descriptors import CriteriaDescriptor, CriteriaSetDescriptor
from .policyrep.exception import RuleUseError, RuleNotConditional from .policyrep.exception import RuleUseError, RuleNotConditional
@ -80,7 +80,7 @@ class TERuleQuery(mixins.MatchObjClass, mixins.MatchPermission, query.PolicyQuer
will match. Default is false. will match. Default is false.
""" """
ruletype = RuletypeDescriptor("validate_te_ruletype") ruletype = CriteriaSetDescriptor(lookup_function="validate_te_ruletype")
source = CriteriaDescriptor("source_regex", "lookup_type_or_attr") source = CriteriaDescriptor("source_regex", "lookup_type_or_attr")
source_regex = False source_regex = False
source_indirect = True source_indirect = True

View File

@ -52,8 +52,7 @@ class MLSRuleTest(unittest.TestCase):
def test_001_validate_ruletype(self): def test_001_validate_ruletype(self):
"""RangeTransition valid rule types.""" """RangeTransition valid rule types."""
# no return value means a return of None self.assertEqual("range_transition", validate_ruletype("range_transition"))
self.assertIsNone(validate_ruletype(["range_transition"]))
def test_002_validate_ruletype_invalid(self): def test_002_validate_ruletype_invalid(self):
"""RangeTransition valid rule types.""" """RangeTransition valid rule types."""

View File

@ -49,7 +49,7 @@ class RoleAllowTest(unittest.TestCase):
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
self.assertIsNone(validate_ruletype(["allow"])) self.assertEqual("allow", validate_ruletype("allow"))
def test_002_validate_ruletype_invalid(self): def test_002_validate_ruletype_invalid(self):
"""RoleAllow valid rule types.""" """RoleAllow valid rule types."""
@ -120,8 +120,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."""
# no return value means a return of None self.assertEqual("role_transition", validate_ruletype("role_transition"))
self.assertIsNone(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."""

View File

@ -62,8 +62,8 @@ class AVRuleTest(unittest.TestCase):
def test_001_validate_ruletype(self): def test_001_validate_ruletype(self):
"""AVRule valid rule types.""" """AVRule valid rule types."""
# no return value means a return of None for r in ["allow", "neverallow", "auditallow", "dontaudit"]:
self.assertIsNone(validate_ruletype(["allow", "neverallow", "auditallow", "dontaudit"])) self.assertEqual(r, validate_ruletype(r))
def test_002_validate_ruletype_invalid(self): def test_002_validate_ruletype_invalid(self):
"""AVRule valid rule types.""" """AVRule valid rule types."""
@ -193,8 +193,8 @@ class TERuleTest(unittest.TestCase):
def test_001_validate_ruletype(self): def test_001_validate_ruletype(self):
"""TERule valid rule types.""" """TERule valid rule types."""
# no return value means a return of None for r in ["type_transition", "type_change", "type_member"]:
self.assertIsNone(validate_ruletype(["type_transition", "type_change", "type_member"])) self.assertEqual(r, validate_ruletype(r))
def test_002_validate_ruletype_invalid(self): def test_002_validate_ruletype_invalid(self):
"""TERule valid rule types.""" """TERule valid rule types."""