PolicyDifference: implement sensitivities diff

Closes #34
This commit is contained in:
Chris PeBenito 2016-01-09 09:01:52 -05:00
parent 8b136a007c
commit 2bd871ae18
6 changed files with 126 additions and 10 deletions

32
sediff
View File

@ -355,6 +355,38 @@ try:
print()
if all_differences or args.sensitivity:
if diff.added_sensitivities or diff.removed_sensitivities or diff.modified_sensitivities \
or args.sensitivity:
print("Sensitivities ({0} Added, {1} Removed, {2} Modified)".format(
len(diff.added_sensitivities), len(diff.removed_sensitivities),
len(diff.modified_sensitivities)))
if diff.added_sensitivities and not args.stats:
print(" Added Sensitivites: {0}".format(len(diff.added_sensitivities)))
for s in sorted(diff.added_sensitivities):
print(" + {0}".format(s))
if diff.removed_sensitivities and not args.stats:
print(" Removed Sensitivities: {0}".format(len(diff.removed_sensitivities)))
for s in sorted(diff.removed_sensitivities):
print(" - {0}".format(s))
if diff.modified_sensitivities and not args.stats:
print(" Modified Sensitivities: {0}".format(len(diff.modified_sensitivities)))
for name, mod in sorted(diff.modified_sensitivities.items()):
change = []
if mod.added_aliases:
change.append("{0} Added Aliases".format(len(mod.added_aliases)))
if mod.removed_aliases:
change.append("{0} Removed Aliases".format(len(mod.removed_aliases)))
print(" * {0} ({1})".format(name, ", ".join(change)))
print(" Aliases:")
for a in sorted(mod.added_aliases):
print(" + {0}".format(a))
for a in sorted(mod.removed_aliases):
print(" - {0}".format(a))
print()
if all_differences or args.allow:
if diff.added_allows or diff.removed_allows or diff.modified_allows or args.allow:
print("Allow Rules ({0} Added, {1} Removed, {2} Modified)".format(

View File

@ -18,7 +18,7 @@
#
from .bool import BooleansDifference
from .commons import CommonDifference
from .mls import CategoriesDifference
from .mls import CategoriesDifference, SensitivitiesDifference
from .mlsrules import MLSRulesDifference
from .objclass import ObjClassDifference
from .rbacrules import RBACRulesDifference
@ -38,6 +38,7 @@ class PolicyDifference(BooleansDifference,
ObjClassDifference,
RBACRulesDifference,
RolesDifference,
SensitivitiesDifference,
TERulesDifference,
TypeAttributesDifference,
TypesDifference,

View File

@ -25,6 +25,10 @@ modified_cat_record = namedtuple("modified_category", ["added_aliases",
"removed_aliases",
"matched_aliases"])
modified_sens_record = namedtuple("modified_sensitivity", ["added_aliases",
"removed_aliases",
"matched_aliases"])
class CategoriesDifference(Difference):
@ -68,6 +72,50 @@ class CategoriesDifference(Difference):
self.modified_categories = None
class SensitivitiesDifference(Difference):
"""Determine the difference in sensitivities between two policies."""
added_sensitivities = DiffResultDescriptor("diff_sensitivities")
removed_sensitivities = DiffResultDescriptor("diff_sensitivities")
modified_sensitivities = DiffResultDescriptor("diff_sensitivities")
def diff_sensitivities(self):
"""Generate the difference in sensitivities between the policies."""
self.log.info(
"Generating sensitivity differences from {0.left_policy} to {0.right_policy}".
format(self))
self.added_sensitivities, self.removed_sensitivities, matched_sensitivities = \
self._set_diff(
(SymbolWrapper(s) for s in self.left_policy.sensitivities()),
(SymbolWrapper(s) for s in self.right_policy.sensitivities()))
self.modified_sensitivities = dict()
for left_category, right_category in matched_sensitivities:
# Criteria for modified sensitivities
# 1. change to aliases
added_aliases, removed_aliases, matched_aliases = self._set_diff(
left_category.aliases(), right_category.aliases())
if added_aliases or removed_aliases:
self.modified_sensitivities[left_category] = modified_sens_record(added_aliases,
removed_aliases,
matched_aliases)
#
# Internal functions
#
def _reset_diff(self):
"""Reset diff results on policy changes."""
self.log.debug("Resetting sensitivity differences")
self.added_sensitivities = None
self.removed_sensitivities = None
self.modified_sensitivities = None
class LevelWrapper(Wrapper):
"""Wrap levels to allow comparisons."""

View File

@ -951,6 +951,29 @@ class PolicyDifferenceTest(ValidateRule, unittest.TestCase):
self.assertFalse(self.diff.modified_categories["c0"].added_aliases)
self.assertEqual(set(["eggs"]), self.diff.modified_categories["c0"].removed_aliases)
#
# Sensitivity
#
def test_added_sensitivities(self):
"""Diff: added sensitivities."""
self.assertSetEqual(set(["s46"]), self.diff.added_sensitivities)
def test_removed_sensitivities(self):
"""Diff: removed sensitivities."""
self.assertSetEqual(set(["s47"]), self.diff.removed_sensitivities)
def test_modified_sensitivities(self):
"""Diff: modified sensitivities."""
self.assertEqual(2, len(self.diff.modified_sensitivities))
# add alias
self.assertEqual(set(["al4"]), self.diff.modified_sensitivities["s1"].added_aliases)
self.assertFalse(self.diff.modified_sensitivities["s1"].removed_aliases)
# remove alias
self.assertFalse(self.diff.modified_sensitivities["s0"].added_aliases)
self.assertEqual(set(["al2"]), self.diff.modified_sensitivities["s0"].removed_aliases)
class PolicyDifferenceTestNoDiff(unittest.TestCase):
@ -1175,3 +1198,15 @@ class PolicyDifferenceTestNoDiff(unittest.TestCase):
def test_modified_categories(self):
"""NoDiff: no modified categories."""
self.assertFalse(self.diff.modified_categories)
def test_added_sensitivities(self):
"""NoDiff: no added sensitivities."""
self.assertFalse(self.diff.added_sensitivities)
def test_removed_sensitivities(self):
"""NoDiff: no removed sensitivities."""
self.assertFalse(self.diff.removed_sensitivities)
def test_modified_sensitivities(self):
"""NoDiff: no modified sensitivities."""
self.assertFalse(self.diff.modified_sensitivities)

View File

@ -92,8 +92,8 @@ class modified_remove_perm
class modified_change_common
inherits removed_common
sensitivity s0;
sensitivity s1;
sensitivity s0 alias { al1 al2 };
sensitivity s1 alias { al3 };
sensitivity s2;
sensitivity s3;
sensitivity s40;
@ -102,9 +102,9 @@ sensitivity s42;
sensitivity s43;
sensitivity s44;
sensitivity s45;
sensitivity s46;
sensitivity s47;
dominance { s0 s1 s2 s3 s40 s41 s42 s43 s44 s45 s46 }
dominance { s0 s1 s2 s3 s40 s41 s42 s43 s44 s45 s47 }
category c0 alias { spam eggs };
category c1 alias { bar };
@ -124,7 +124,7 @@ level s42:c0.c4;
level s43:c0.c4;
level s44:c0.c4;
level s45:c0.c4;
level s46:c0.c4;
level s47:c0.c4;
#some constraints
mlsconstrain infoflow hi_r ((l1 dom l2) or (t1 == mls_exempt));
@ -593,7 +593,7 @@ role_transition role_tr_matched_source role_tr_matched_target:infoflow3 role_tr_
################################################################################
#users
user system roles system level s0 range s0 - s46:c1.c4;
user system roles system level s0 range s0;
user removed_user roles system level s0 range s0;

View File

@ -92,8 +92,8 @@ class modified_remove_perm
class modified_change_common
inherits added_common
sensitivity s0;
sensitivity s1;
sensitivity s0 alias { al1 };
sensitivity s1 alias { al3 al4 };
sensitivity s2;
sensitivity s3;
sensitivity s40;
@ -593,7 +593,7 @@ role_transition role_tr_matched_source role_tr_matched_target:infoflow3 role_tr_
################################################################################
#users
user system roles system level s0 range s0 - s46:c1.c4;
user system roles system level s0 range s0;
user added_user roles system level s1 range s1;