Extend indirect handling for rule queries.

Range_transitions are expanded in the qpol representation, but attributes
can still be used as criteria.

Hard code default role to indirect to handle role attributes in the
criteria.  Role attributes don't survive in the qpol
representation yet, so this is a forward-looking change.

Similarly hard code the default type matching to indirect so attributes can
be used for default type criteria in type_* rules.  Adjust default criteria
lookup function accordingly.

Related to #111
This commit is contained in:
Chris PeBenito 2016-03-16 14:06:49 -04:00
parent 5063edd111
commit bb5cffd44e
7 changed files with 174 additions and 7 deletions

View File

@ -46,8 +46,10 @@ class MLSRuleQuery(mixins.MatchObjClass, query.PolicyQuery):
ruletype = CriteriaSetDescriptor(lookup_function="validate_mls_ruletype")
source = CriteriaDescriptor("source_regex", "lookup_type_or_attr")
source_regex = False
source_indirect = True
target = CriteriaDescriptor("target_regex", "lookup_type_or_attr")
target_regex = False
target_indirect = True
tclass = CriteriaSetDescriptor("tclass_regex", "lookup_class")
tclass_regex = False
default = CriteriaDescriptor(lookup_function="lookup_range")
@ -64,8 +66,10 @@ class MLSRuleQuery(mixins.MatchObjClass, query.PolicyQuery):
"""Generator which yields all matching MLS rules."""
self.log.info("Generating MLS rule results from {0.policy}".format(self))
self.log.debug("Ruletypes: {0.ruletype}".format(self))
self.log.debug("Source: {0.source!r}, regex: {0.source_regex}".format(self))
self.log.debug("Target: {0.target!r}, regex: {0.target_regex}".format(self))
self.log.debug("Source: {0.source!r}, indirect: {0.source_indirect}, "
"regex: {0.source_regex}".format(self))
self.log.debug("Target: {0.target!r}, indirect: {0.target_indirect}, "
"regex: {0.target_regex}".format(self))
self.log.debug("Class: {0.tclass!r}, regex: {0.tclass_regex}".format(self))
self.log.debug("Default: {0.default!r}, overlap: {0.default_overlap}, "
"subset: {0.default_subset}, superset: {0.default_superset}, "
@ -82,18 +86,20 @@ class MLSRuleQuery(mixins.MatchObjClass, query.PolicyQuery):
#
# Matching on source type
#
if self.source and not self._match_regex(
if self.source and not self._match_indirect_regex(
rule.source,
self.source,
self.source_indirect,
self.source_regex):
continue
#
# Matching on target type
#
if self.target and not self._match_regex(
if self.target and not self._match_indirect_regex(
rule.target,
self.target,
self.target_indirect,
self.target_regex):
continue

View File

@ -139,9 +139,13 @@ class RBACRuleQuery(mixins.MatchObjClass, query.PolicyQuery):
#
if self.default:
try:
if not self._match_regex(
# because default role is always a single
# role, hard-code indirect to True
# so the criteria can be an attribute
if not self._match_indirect_regex(
rule.default,
self.default,
True,
self.default_regex):
continue
except RuleUseError:

View File

@ -87,7 +87,7 @@ class TERuleQuery(mixins.MatchObjClass, mixins.MatchPermission, query.PolicyQuer
target = CriteriaDescriptor("target_regex", "lookup_type_or_attr")
target_regex = False
target_indirect = True
default = CriteriaDescriptor("default_regex", "lookup_type")
default = CriteriaDescriptor("default_regex", "lookup_type_or_attr")
default_regex = False
boolean = CriteriaSetDescriptor("boolean_regex", "lookup_boolean")
boolean_regex = False
@ -160,9 +160,13 @@ class TERuleQuery(mixins.MatchObjClass, mixins.MatchPermission, query.PolicyQuer
#
if self.default:
try:
if not self._match_regex(
# because default type is always a single
# type, hard-code indirect to True
# so the criteria can be an attribute
if not self._match_indirect_regex(
rule.default,
self.default,
True,
self.default_regex):
continue
except RuleUseError:

View File

@ -158,6 +158,24 @@ range_transition test4a1 test4a1:infoflow s1;
range_transition test4a2 test4a2:infoflow2 s2;
range_transition test4FAIL test4FAIL:infoflow s3;
# test 5
# https://github.com/TresysTechnology/setools/issues/111
# Fix search with source criteria that is an attribute, indirect match
#
# ruletype: unset
# source: test5b, indirect
# target: unset
# class: unset
# default: unset
# boolean: unset
attribute test5a;
attribute test5b;
type test5t1, test5a, test5b;
type test5t2, test5b;
type test5target;
range_transition test5t1 test5target:infoflow s1;
range_transition test5t2 test5target:infoflow7 s2;
# test 10
# ruletype: unset
# source: unset
@ -212,6 +230,24 @@ range_transition test13a1 test13a1:infoflow s0;
range_transition test13a2 test13a2:infoflow s1;
range_transition test13FAIL test13FAIL:infoflow s2;
# test 14
# https://github.com/TresysTechnology/setools/issues/111
# Fix search with target criteria that is an attribute, indirect match
#
# ruletype: unset
# source: test14b, indirect
# target: unset
# class: unset
# default: unset
# boolean: unset
attribute test14a;
attribute test14b;
type test14t1, test14a, test14b;
type test14t2, test14b;
type test14source;
range_transition test14source test14t1:infoflow s1;
range_transition test14source test14t2:infoflow7 s2;
# test 20
# ruletype: unset
# source: unset

View File

@ -64,6 +64,16 @@ class MLSRuleQueryTest(mixins.ValidateRule, unittest.TestCase):
self.validate_rule(r[0], "range_transition", "test3s", "test3t", "infoflow", "s1")
self.validate_rule(r[1], "range_transition", "test3s", "test3t", "infoflow2", "s2")
def test_005_issue111(self):
"""MLS rule query with attribute source criteria, indirect match."""
# https://github.com/TresysTechnology/setools/issues/111
q = MLSRuleQuery(self.p, source="test5b", source_indirect=True)
r = sorted(q.results())
self.assertEqual(len(r), 2)
self.validate_rule(r[0], "range_transition", "test5t1", "test5target", "infoflow", "s1")
self.validate_rule(r[1], "range_transition", "test5t2", "test5target", "infoflow7", "s2")
def test_010_target_direct(self):
"""MLS rule query with exact, direct, target match."""
q = MLSRuleQuery(
@ -83,6 +93,16 @@ class MLSRuleQueryTest(mixins.ValidateRule, unittest.TestCase):
self.assertEqual(len(r), 1)
self.validate_rule(r[0], "range_transition", "test12s", "test12aFAIL", "infoflow", "s2")
def test_014_issue111(self):
"""MLS rule query with attribute target criteria, indirect match."""
# https://github.com/TresysTechnology/setools/issues/111
q = MLSRuleQuery(self.p, target="test14b", target_indirect=True)
r = sorted(q.results())
self.assertEqual(len(r), 2)
self.validate_rule(r[0], "range_transition", "test14source", "test14t1", "infoflow", "s1")
self.validate_rule(r[1], "range_transition", "test14source", "test14t2", "infoflow7", "s2")
@unittest.skip("Setting tclass to a string is no longer supported.")
def test_020_class(self):
"""MLS rule query with exact object class match."""

View File

@ -347,6 +347,65 @@ if (test202c || test202b) {
allow test202t2 self:infoflow7 super_unmapped;
}
# test 300
# https://github.com/TresysTechnology/setools/issues/111
# Fix search with source criteria that is an attribute, indirect match
#
# ruletype: unset
# source: test300b, indirect
# target: unset
# class: unset
# default: unset
# boolean: unset
attribute test300a;
attribute test300b;
type test300t1, test300a, test300b;
type test300t2, test300b;
type test300t3, test300a;
type test300target;
allow test300a test300target:infoflow7 hi_w;
allow test300t1 self:infoflow7 hi_r;
allow test300t2 self:infoflow7 med_w;
allow test300b test300target:infoflow7 super_w;
# test 301
# https://github.com/TresysTechnology/setools/issues/111
# Fix search with target criteria that is an attribute, indirect match
#
# ruletype: unset
# source: unset
# target: test301b, indirect
# class: unset
# default: unset
# boolean: unset
attribute test301a;
attribute test301b;
type test301t1, test301a, test301b;
type test301t2, test301b;
type test301t3, test301a;
type test301source;
allow test301source test301a:infoflow7 hi_w;
allow test301t1 self:infoflow7 hi_r;
allow test301t2 self:infoflow7 med_w;
allow test301source test301b:infoflow7 super_w;
# test 302
# https://github.com/TresysTechnology/setools/issues/111
# Fix search with default type criteria that is an attribute
#
# ruletype: unset
# source: unset
# target: unset
# class: unset
# default: test302b
# boolean: unset
attribute test302;
type test302t1, test302;
type test302t2, test302;
type test302source;
type_transition test302source test302t1:infoflow7 test302t1;
type_transition test302source test302t2:infoflow7 test302t2;
################################################################################
#users

View File

@ -244,3 +244,41 @@ class TERuleQueryTest(mixins.ValidateRule, unittest.TestCase):
set(["super_none"]), cond="test202a")
self.validate_rule(r[1], "allow", "test202t2", "test202t2", "infoflow7",
set(["super_unmapped"]), cond="test202b || test202c")
def test_300_issue111(self):
"""TE rule query with attribute source criteria, indirect match."""
# https://github.com/TresysTechnology/setools/issues/111
q = TERuleQuery(self.p, source="test300b", source_indirect=True)
r = sorted(q.results())
self.assertEqual(len(r), 4)
self.validate_rule(r[0], "allow", "test300a", "test300target", "infoflow7", set(["hi_w"]))
self.validate_rule(r[1], "allow", "test300b", "test300target", "infoflow7",
set(["super_w"]))
self.validate_rule(r[2], "allow", "test300t1", "test300t1", "infoflow7", set(["hi_r"]))
self.validate_rule(r[3], "allow", "test300t2", "test300t2", "infoflow7", set(["med_w"]))
def test_301_issue111(self):
"""TE rule query with attribute target criteria, indirect match."""
# https://github.com/TresysTechnology/setools/issues/111
q = TERuleQuery(self.p, target="test301b", target_indirect=True)
r = sorted(q.results())
self.assertEqual(len(r), 4)
self.validate_rule(r[0], "allow", "test301source", "test301a", "infoflow7", set(["hi_w"]))
self.validate_rule(r[1], "allow", "test301source", "test301b", "infoflow7",
set(["super_w"]))
self.validate_rule(r[2], "allow", "test301t1", "test301t1", "infoflow7", set(["hi_r"]))
self.validate_rule(r[3], "allow", "test301t2", "test301t2", "infoflow7", set(["med_w"]))
def test_302_issue111(self):
"""TE rule query with attribute default type criteria."""
# https://github.com/TresysTechnology/setools/issues/111
q = TERuleQuery(self.p, default="test302")
r = sorted(q.results())
self.assertEqual(len(r), 2)
self.validate_rule(r[0], "type_transition", "test302source", "test302t1", "infoflow7",
"test302t1")
self.validate_rule(r[1], "type_transition", "test302source", "test302t2", "infoflow7",
"test302t2")