ContextQuery: implement range matching criteria.

Implement unit tests on FSUseQuery for initial testing.

closes #22
This commit is contained in:
Chris PeBenito 2015-02-24 09:44:12 -05:00
parent 0b72591b45
commit fa02fdfbb5
9 changed files with 338 additions and 27 deletions

View File

@ -30,7 +30,7 @@ class ContextQuery(query.PolicyQuery):
user, user_regex, user_recomp,
role, role_regex, role_recomp,
type_, type_regex, type_recomp,
range_):
range_, range_subset, range_overlap, range_superset, range_proper):
"""
Match the context with optional regular expression.
@ -49,6 +49,15 @@ class ContextQuery(query.PolicyQuery):
will be used on the type.
type_recomp The compiled type regular expression.
range_ The range to match in the context.
range_subset If true, the criteria will match if it
is a subset of the context's range.
range_overlap If true, the criteria will match if it
overlaps any of the context's range.
range_superset If true, the criteria will match if it
is a superset of the context's range.
range_proper If true, use proper superset/subset
on range matching operations.
No effect if not using set operations.
"""
if user and not query.PolicyQuery._match_regex(
@ -72,8 +81,14 @@ class ContextQuery(query.PolicyQuery):
type_recomp):
return False
if range_:
raise NotImplementedError
if range_ and not query.PolicyQuery._match_range(
(context.range_.low, context.range_.high),
(range_.low, range_.high),
range_subset,
range_overlap,
range_superset,
range_proper):
return False
return True
@ -157,10 +172,35 @@ class ContextQuery(query.PolicyQuery):
Set the criteria for matching the context's range.
Parameter:
range_ Range to match the context's range.
range_ Criteria to match the context's range.
Keyword Parameters:
range_subset If true, the criteria will match if it is a subset
of the context's range.
range_overlap If true, the criteria will match if it overlaps
any of the context's range.
range_superset If true, the criteria will match if it is a superset
of the context's range.
range_proper If true, use proper superset/subset operations.
No effect if not using set operations.
Exceptions:
NameError Invalid keyword option.
NameError Invalid keyword option.
"""
self.range_ = range_
if range_:
self.range_ = self.policy.lookup_range(range_)
else:
self.range_ = None
for k in list(opts.keys()):
if k == "subset":
self.range_subset = opts[k]
elif k == "overlap":
self.range_overlap = opts[k]
elif k == "superset":
self.range_superset = opts[k]
elif k == "proper":
self.range_proper = opts[k]
else:
raise NameError("Invalid name option: {0}".format(k))

View File

@ -32,7 +32,8 @@ class FSUseQuery(contextquery.ContextQuery):
user="", user_regex=False,
role="", role_regex=False,
type_="", type_regex=False,
range_=""):
range_="", range_overlap=False, range_subset=False,
range_superset=False, range_proper=False):
"""
Parameters:
policy The policy to query.
@ -51,6 +52,14 @@ class FSUseQuery(contextquery.ContextQuery):
type_regex If true, regular expression matching
will be used on the type.
range_ The criteria to match the context's range.
range_subset If true, the criteria will match if it is a subset
of the context's range.
range_overlap If true, the criteria will match if it overlaps
any of the context's range.
range_superset If true, the criteria will match if it is a superset
of the context's range.
range_proper If true, use proper superset/subset operations.
No effect if not using set operations.
"""
self.policy = policy
@ -60,7 +69,8 @@ class FSUseQuery(contextquery.ContextQuery):
self.set_user(user, regex=user_regex)
self.set_role(role, regex=role_regex)
self.set_type(type_, regex=type_regex)
self.set_range(range_)
self.set_range(range_, overlap=range_overlap, subset=range_subset,
superset=range_superset, proper=range_proper)
def results(self):
"""Generator which yields all matching fs_use_* statements."""
@ -87,7 +97,11 @@ class FSUseQuery(contextquery.ContextQuery):
self.type_,
self.type_regex,
self.type_cmp,
self.range_):
self.range_,
self.range_subset,
self.range_overlap,
self.range_superset,
self.range_proper):
continue
yield fsu

View File

@ -33,7 +33,8 @@ class GenfsconQuery(contextquery.ContextQuery):
user="", user_regex=False,
role="", role_regex=False,
type_="", type_regex=False,
range_=""):
range_="", range_overlap=False, range_subset=False,
range_superset=False, range_proper=False):
"""
Parameters:
policy The policy to query.
@ -54,6 +55,14 @@ class GenfsconQuery(contextquery.ContextQuery):
type_regex If true, regular expression matching
will be used on the type.
range_ The criteria to match the context's range.
range_subset If true, the criteria will match if it is a subset
of the context's range.
range_overlap If true, the criteria will match if it overlaps
any of the context's range.
range_superset If true, the criteria will match if it is a superset
of the context's range.
range_proper If true, use proper superset/subset operations.
No effect if not using set operations.
"""
self.policy = policy
@ -64,7 +73,8 @@ class GenfsconQuery(contextquery.ContextQuery):
self.set_user(user, regex=user_regex)
self.set_role(role, regex=role_regex)
self.set_type(type_, regex=type_regex)
self.set_range(range_)
self.set_range(range_, overlap=range_overlap, subset=range_subset,
superset=range_superset, proper=range_proper)
def results(self):
"""Generator which yields all matching genfscons."""
@ -98,7 +108,11 @@ class GenfsconQuery(contextquery.ContextQuery):
self.type_,
self.type_regex,
self.type_cmp,
self.range_):
self.range_,
self.range_subset,
self.range_overlap,
self.range_superset,
self.range_proper):
continue
yield g

View File

@ -29,7 +29,8 @@ class InitialSIDQuery(compquery.ComponentQuery, contextquery.ContextQuery):
user="", user_regex=False,
role="", role_regex=False,
type_="", type_regex=False,
range_=""):
range_="", range_overlap=False, range_subset=False,
range_superset=False, range_proper=False):
"""
Parameters:
policy The policy to query.
@ -44,6 +45,14 @@ class InitialSIDQuery(compquery.ComponentQuery, contextquery.ContextQuery):
type_regex If true, regular expression matching
will be used on the type.
range_ The criteria to match the context's range.
range_subset If true, the criteria will match if it is a subset
of the context's range.
range_overlap If true, the criteria will match if it overlaps
any of the context's range.
range_superset If true, the criteria will match if it is a superset
of the context's range.
range_proper If true, use proper superset/subset operations.
No effect if not using set operations.
"""
self.policy = policy
@ -52,7 +61,8 @@ class InitialSIDQuery(compquery.ComponentQuery, contextquery.ContextQuery):
self.set_user(user, regex=user_regex)
self.set_role(role, regex=role_regex)
self.set_type(type_, regex=type_regex)
self.set_range(range_)
self.set_range(range_, overlap=range_overlap, subset=range_subset,
superset=range_superset, proper=range_proper)
def results(self):
"""Generator which yields all matching initial SIDs."""
@ -76,7 +86,11 @@ class InitialSIDQuery(compquery.ComponentQuery, contextquery.ContextQuery):
self.type_,
self.type_regex,
self.type_cmp,
self.range_):
self.range_,
self.range_subset,
self.range_overlap,
self.range_superset,
self.range_proper):
continue
yield i

View File

@ -29,7 +29,8 @@ class NetifconQuery(compquery.ComponentQuery, contextquery.ContextQuery):
user="", user_regex=False,
role="", role_regex=False,
type_="", type_regex=False,
range_=""):
range_="", range_overlap=False, range_subset=False,
range_superset=False, range_proper=False):
"""
Parameters:
policy The policy to query.
@ -44,6 +45,14 @@ class NetifconQuery(compquery.ComponentQuery, contextquery.ContextQuery):
type_regex If true, regular expression matching
will be used on the type.
range_ The criteria to match the context's range.
range_subset If true, the criteria will match if it is a subset
of the context's range.
range_overlap If true, the criteria will match if it overlaps
any of the context's range.
range_superset If true, the criteria will match if it is a superset
of the context's range.
range_proper If true, use proper superset/subset operations.
No effect if not using set operations.
"""
self.policy = policy
@ -52,7 +61,8 @@ class NetifconQuery(compquery.ComponentQuery, contextquery.ContextQuery):
self.set_user(user, regex=user_regex)
self.set_role(role, regex=role_regex)
self.set_type(type_, regex=type_regex)
self.set_range(range_)
self.set_range(range_, overlap=range_overlap, subset=range_subset,
superset=range_superset, proper=range_proper)
def results(self):
"""Generator which yields all matching netifcons."""
@ -76,7 +86,11 @@ class NetifconQuery(compquery.ComponentQuery, contextquery.ContextQuery):
self.type_,
self.type_regex,
self.type_cmp,
self.range_):
self.range_,
self.range_subset,
self.range_overlap,
self.range_superset,
self.range_proper):
continue
yield netif

View File

@ -38,7 +38,8 @@ class NodeconQuery(contextquery.ContextQuery):
user="", user_regex=False,
role="", role_regex=False,
type_="", type_regex=False,
range_=""):
range_="", range_overlap=False, range_subset=False,
range_superset=False, range_proper=False):
"""
Parameters:
policy The policy to query.
@ -56,6 +57,14 @@ class NodeconQuery(contextquery.ContextQuery):
type_regex If true, regular expression matching
will be used on the type.
range_ The criteria to match the context's range.
range_subset If true, the criteria will match if it is a subset
of the context's range.
range_overlap If true, the criteria will match if it overlaps
any of the context's range.
range_superset If true, the criteria will match if it is a superset
of the context's range.
range_proper If true, use proper superset/subset operations.
No effect if not using set operations.
"""
self.policy = policy
@ -65,7 +74,8 @@ class NodeconQuery(contextquery.ContextQuery):
self.set_user(user, regex=user_regex)
self.set_role(role, regex=role_regex)
self.set_type(type_, regex=type_regex)
self.set_range(range_)
self.set_range(range_, overlap=range_overlap, subset=range_subset,
superset=range_superset, proper=range_proper)
def results(self):
"""Generator which yields all matching nodecons."""
@ -115,7 +125,11 @@ class NodeconQuery(contextquery.ContextQuery):
self.type_,
self.type_regex,
self.type_cmp,
self.range_):
self.range_,
self.range_subset,
self.range_overlap,
self.range_superset,
self.range_proper):
continue
yield n

View File

@ -33,7 +33,8 @@ class PortconQuery(compquery.ComponentQuery, contextquery.ContextQuery):
user="", user_regex=False,
role="", role_regex=False,
type_="", type_regex=False,
range_=""):
range_="", range_overlap=False, range_subset=False,
range_superset=False, range_proper=False):
"""
Parameters:
policy The policy to query.
@ -66,6 +67,14 @@ class PortconQuery(compquery.ComponentQuery, contextquery.ContextQuery):
will be used on the type.
range_ The criteria to match the context's range.
range_subset If true, the criteria will match if it is a subset
of the context's range.
range_overlap If true, the criteria will match if it overlaps
any of the context's range.
range_superset If true, the criteria will match if it is a superset
of the context's range.
range_proper If true, use proper superset/subset operations.
No effect if not using set operations.
"""
self.policy = policy
@ -76,7 +85,8 @@ class PortconQuery(compquery.ComponentQuery, contextquery.ContextQuery):
self.set_user(user, regex=user_regex)
self.set_role(role, regex=role_regex)
self.set_type(type_, regex=type_regex)
self.set_range(range_)
self.set_range(range_, overlap=range_overlap, subset=range_subset,
superset=range_superset, proper=range_proper)
def results(self):
"""Generator which yields all matching portcons."""
@ -107,7 +117,11 @@ class PortconQuery(compquery.ComponentQuery, contextquery.ContextQuery):
self.type_,
self.type_regex,
self.type_cmp,
self.range_):
self.range_,
self.range_subset,
self.range_overlap,
self.range_superset,
self.range_proper):
continue
yield p

View File

@ -56,8 +56,12 @@ inherits infoflow
sensitivity s0;
sensitivity s1;
sensitivity s2;
sensitivity s3;
sensitivity s4;
sensitivity s5;
sensitivity s6;
dominance { s0 s1 s2 }
dominance { s0 s1 s2 s3 s4 s5 s6 }
category c0;
category c1;
@ -69,7 +73,10 @@ category c4;
level s0:c0.c4;
level s1:c0.c4;
level s2:c0.c4;
level s3:c0.c4;
level s4:c0.c4;
level s5:c0.c4;
level s6:c0.c4;
#some constraints
mlsconstrain infoflow hi_r ((l1 dom l2) or (t1 == mls_exempt));
@ -104,7 +111,7 @@ role system types { type40 type41a type41b type41c };
################################################################################
#users
user system roles { system role30_r role31a_r role31b_r role31c_r } level s0 range s0 - s2:c0.c4;
user system roles { system role30_r role31a_r role31b_r role31c_r } level s0 range s0 - s6:c0.c4;
user user20 roles system level s0 range s0 - s2:c0.c4;
user user21a roles system level s0 range s0 - s2:c0.c4;
user user21b roles system level s0 range s0 - s2:c0.c4;
@ -208,6 +215,60 @@ fs_use_xattr test41a system:system:type41a:s0:c0.c1;
fs_use_xattr test41b system:system:type41b:s0:c0.c1;
fs_use_xattr test41c system:system:type41c:s0:c0.c1;
# test 50:
# ruletype: unset
# fs: unset
# user: unset
# role: unset
# type: unset
# range: equal
fs_use_xattr test50 system:system:system:s0:c1 - s0:c0.c4;
# test 51:
# ruletype: unset
# fs: unset
# user: unset
# role: unset
# type: unset
# range: overlap
fs_use_xattr test51 system:system:system:s1:c1 - s1:c1.c3;
# test 52:
# ruletype: unset
# fs: unset
# user: unset
# role: unset
# type: unset
# range: subset
fs_use_xattr test52 system:system:system:s2:c1 - s2:c1.c3;
# test 53:
# ruletype: unset
# fs: unset
# user: unset
# role: unset
# type: unset
# range: superset
fs_use_xattr test53 system:system:system:s3:c1 - s3:c1.c3;
# test 54:
# ruletype: unset
# fs: unset
# user: unset
# role: unset
# type: unset
# range: proper subset
fs_use_xattr test54 system:system:system:s4:c1 - s4:c1.c3;
# test 55:
# ruletype: unset
# fs: unset
# user: unset
# role: unset
# type: unset
# range: proper superset
fs_use_xattr test55 system:system:system:s5:c1 - s5:c1.c3;
#genfscon
genfscon proc / system:object_r:system:s1
genfscon proc /sys system:object_r:system:s0

View File

@ -98,3 +98,129 @@ class FSUseQueryTest(unittest.TestCase):
fsu = sorted(s.fs for s in q.results())
self.assertListEqual(["test41b", "test41c"], fsu)
def test_050_range_exact(self):
"""fs_use_* query with context range exact match"""
q = FSUseQuery(self.p, range_="s0:c1 - s0:c0.c4")
fsu = sorted(s.fs for s in q.results())
self.assertListEqual(["test50"], fsu)
def test_051_range_overlap1(self):
"""fs_use_* query with context range overlap match (equal)"""
q = FSUseQuery(self.p, range_="s1:c1 - s1:c0.c4", range_overlap=True)
fsu = sorted(s.fs for s in q.results())
self.assertListEqual(["test51"], fsu)
def test_051_range_overlap2(self):
"""fs_use_* query with context range overlap match (subset)"""
q = FSUseQuery(self.p, range_="s1:c1,c2 - s1:c0.c3", range_overlap=True)
fsu = sorted(s.fs for s in q.results())
self.assertListEqual(["test51"], fsu)
def test_051_range_overlap3(self):
"""fs_use_* query with context range overlap match (superset)"""
q = FSUseQuery(self.p, range_="s1 - s1:c0.c4", range_overlap=True)
fsu = sorted(s.fs for s in q.results())
self.assertListEqual(["test51"], fsu)
def test_051_range_overlap4(self):
"""fs_use_* query with context range overlap match (overlap low level)"""
q = FSUseQuery(self.p, range_="s1 - s1:c1,c2", range_overlap=True)
fsu = sorted(s.fs for s in q.results())
self.assertListEqual(["test51"], fsu)
def test_051_range_overlap5(self):
"""fs_use_* query with context range overlap match (overlap high level)"""
q = FSUseQuery(self.p, range_="s1:c1,c2 - s1:c0.c4", range_overlap=True)
fsu = sorted(s.fs for s in q.results())
self.assertListEqual(["test51"], fsu)
def test_052_range_subset1(self):
"""fs_use_* query with context range subset match"""
q = FSUseQuery(self.p, range_="s2:c1,c2 - s2:c0.c3", range_overlap=True)
fsu = sorted(s.fs for s in q.results())
self.assertListEqual(["test52"], fsu)
def test_052_range_subset2(self):
"""fs_use_* query with context range subset match (equal)"""
q = FSUseQuery(self.p, range_="s2:c1 - s2:c1.c3", range_overlap=True)
fsu = sorted(s.fs for s in q.results())
self.assertListEqual(["test52"], fsu)
def test_053_range_superset1(self):
"""fs_use_* query with context range superset match"""
q = FSUseQuery(self.p, range_="s3 - s3:c0.c4", range_superset=True)
fsu = sorted(s.fs for s in q.results())
self.assertListEqual(["test53"], fsu)
def test_053_range_superset2(self):
"""fs_use_* query with context range superset match (equal)"""
q = FSUseQuery(self.p, range_="s3:c1 - s3:c1.c3", range_superset=True)
fsu = sorted(s.fs for s in q.results())
self.assertListEqual(["test53"], fsu)
def test_054_range_proper_subset1(self):
"""fs_use_* query with context range proper subset match"""
q = FSUseQuery(self.p, range_="s4:c1,c2", range_subset=True, range_proper=True)
fsu = sorted(s.fs for s in q.results())
self.assertListEqual(["test54"], fsu)
def test_054_range_proper_subset2(self):
"""fs_use_* query with context range proper subset match (equal)"""
q = FSUseQuery(self.p, range_="s4:c1 - s4:c1.c3", range_subset=True, range_proper=True)
fsu = sorted(s.fs for s in q.results())
self.assertListEqual([], fsu)
def test_054_range_proper_subset3(self):
"""fs_use_* query with context range proper subset match (equal low only)"""
q = FSUseQuery(self.p, range_="s4:c1 - s4:c1.c2", range_subset=True, range_proper=True)
fsu = sorted(s.fs for s in q.results())
self.assertListEqual(["test54"], fsu)
def test_054_range_proper_subset4(self):
"""fs_use_* query with context range proper subset match (equal high only)"""
q = FSUseQuery(self.p, range_="s4:c1,c2 - s4:c1.c3", range_subset=True, range_proper=True)
fsu = sorted(s.fs for s in q.results())
self.assertListEqual(["test54"], fsu)
def test_055_range_proper_superset1(self):
"""fs_use_* query with context range proper superset match"""
q = FSUseQuery(self.p, range_="s5 - s5:c0.c4", range_superset=True, range_proper=True)
fsu = sorted(s.fs for s in q.results())
self.assertListEqual(["test55"], fsu)
def test_055_range_proper_superset2(self):
"""fs_use_* query with context range proper superset match (equal)"""
q = FSUseQuery(self.p, range_="s5:c1 - s5:c1.c3", range_superset=True, range_proper=True)
fsu = sorted(s.fs for s in q.results())
self.assertListEqual([], fsu)
def test_055_range_proper_superset3(self):
"""fs_use_* query with context range proper superset match (equal low)"""
q = FSUseQuery(self.p, range_="s5:c1 - s5:c1.c4", range_superset=True, range_proper=True)
fsu = sorted(s.fs for s in q.results())
self.assertListEqual(["test55"], fsu)
def test_055_range_proper_superset4(self):
"""fs_use_* query with context range proper superset match (equal high)"""
q = FSUseQuery(self.p, range_="s5 - s5:c1.c3", range_superset=True, range_proper=True)
fsu = sorted(s.fs for s in q.results())
self.assertListEqual(["test55"], fsu)