PolicyDifference: implement common permission set diff

Closes #27
This commit is contained in:
Chris PeBenito 2015-12-18 19:39:02 -05:00
parent 36546e76ac
commit b3dbe6a8b3
5 changed files with 135 additions and 0 deletions

28
sediff
View File

@ -82,6 +82,34 @@ try:
p2 = setools.SELinuxPolicy(args.POLICY2[0])
diff = setools.PolicyDifference(p1, p2)
if diff.added_commons or diff.removed_commons or diff.modified_commons:
print("Commons ({0} Added, {1} Removed, {2} Modified)".format(len(diff.added_commons),
len(diff.removed_commons),
len(diff.modified_commons)))
if diff.added_commons:
print(" Added Commons: {0}".format(len(diff.added_commons)))
for c in sorted(diff.added_commons):
print(" + {0}".format(c))
if diff.removed_commons:
print(" Removed Commons: {0}".format(len(diff.removed_commons)))
for c in sorted(diff.removed_commons):
print(" - {0}".format(c))
if diff.modified_commons:
print(" Modified Commons: {0}".format(len(diff.modified_commons)))
for name, mod in sorted(diff.modified_commons.items()):
change = []
if mod.added_perms:
change.append("{0} Added permissions".format(len(mod.added_perms)))
if mod.removed_perms:
change.append("{0} Removed permissions".format(len(mod.removed_perms)))
print(" * {0} ({1})".format(name, ", ".join(change)))
for p in sorted(mod.added_perms):
print(" + {0}".format(p))
for p in sorted(mod.removed_perms):
print(" - {0}".format(p))
print()
if diff.added_roles or diff.removed_roles or diff.modified_roles:
print("Roles ({0} Added, {1} Removed, {2} Modified)".format(len(diff.added_roles),
len(diff.removed_roles),

View File

@ -23,6 +23,10 @@ from weakref import WeakKeyDictionary
__all__ = ['PolicyDifference']
modified_commons_record = namedtuple("modified_common", ["added_perms",
"removed_perms",
"matched_perms"])
modified_roles_record = namedtuple("modified_role", ["added_types",
"removed_types",
"matched_types"])
@ -106,6 +110,38 @@ class PolicyDifference(object):
self._right_policy = policy
self._reset_diff()
#
# Common differences
#
added_commons = DiffResultDescriptor("diff_commons")
removed_commons = DiffResultDescriptor("diff_commons")
modified_commons = DiffResultDescriptor("diff_commons")
def diff_commons(self):
"""Generate the difference in commons between the policies."""
self.log.info(
"Generating common differences from {0.left_policy} to {0.right_policy}".format(self))
self.added_commons, self.removed_commons, matched_commons = self._set_diff(
self.left_policy.commons(), self.right_policy.commons())
self.modified_commons = dict()
for name in matched_commons:
# Criteria for modified commons
# 1. change to permissions
left_common = self.left_policy.lookup_common(name)
right_common = self.right_policy.lookup_common(name)
added_perms, removed_perms, matched_perms = self._set_diff(left_common.perms,
right_common.perms)
if added_perms or removed_perms:
self.modified_commons[name] = modified_commons_record(added_perms,
removed_perms,
matched_perms)
#
# Role differences
#
@ -190,6 +226,9 @@ class PolicyDifference(object):
#
def _reset_diff(self):
"""Reset diff results on policy changes."""
self.added_commons = None
self.removed_commons = None
self.modified_commons = None
self.added_roles = None
self.removed_roles = None
self.modified_roles = None

View File

@ -141,6 +141,30 @@ class PolicyDifferenceTest(unittest.TestCase):
self.diff.modified_roles["modified_remove_type"].removed_types)
self.assertFalse(self.diff.modified_roles["modified_remove_type"].added_types)
def test_added_common(self):
"""Diff: added common."""
self.assertSetEqual(set(["added_common"]), self.diff.added_commons)
def test_removed_common(self):
"""Diff: removed common."""
self.assertSetEqual(set(["removed_common"]), self.diff.removed_commons)
def test_modified_common_count(self):
"""Diff: modified common count."""
self.assertEqual(2, len(self.diff.modified_commons))
def test_modified_common_add_perm(self):
"""Diff: modified common with added perm."""
self.assertSetEqual(set(["added_perm"]),
self.diff.modified_commons["modified_add_perm"].added_perms)
self.assertFalse(self.diff.modified_commons["modified_add_perm"].removed_perms)
def test_modified_common_remove_perm(self):
"""Diff: modified common with removed perm."""
self.assertSetEqual(set(["removed_perm"]),
self.diff.modified_commons["modified_remove_perm"].removed_perms)
self.assertFalse(self.diff.modified_commons["modified_remove_perm"].added_perms)
class PolicyDifferenceTestNoDiff(unittest.TestCase):
@ -173,3 +197,15 @@ class PolicyDifferenceTestNoDiff(unittest.TestCase):
def test_modified_roles(self):
"""NoDiff: no modified roles."""
self.assertFalse(self.diff.modified_roles)
def test_added_commons(self):
"""NoDiff: no added commons."""
self.assertFalse(self.diff.added_commons)
def test_removed_commons(self):
"""NoDiff: no removed commons."""
self.assertFalse(self.diff.removed_commons)
def test_modified_commons(self):
"""NoDiff: no modified commons."""
self.assertFalse(self.diff.modified_commons)

View File

@ -19,6 +19,22 @@ common infoflow
hi_r
}
common removed_common
{
old_com
}
common modified_remove_perm
{
same_perm
removed_perm
}
common modified_add_perm
{
matched_perm
}
class infoflow
inherits infoflow

View File

@ -19,6 +19,22 @@ common infoflow
hi_r
}
common added_common
{
new_com
}
common modified_remove_perm
{
same_perm
}
common modified_add_perm
{
matched_perm
added_perm
}
class infoflow
inherits infoflow