mirror of
https://github.com/SELinuxProject/setools
synced 2025-04-11 03:51:26 +00:00
parent
3a82ebd9d3
commit
00bc854968
30
sediff
30
sediff
@ -395,6 +395,36 @@ try:
|
||||
|
||||
print()
|
||||
|
||||
if all_differences or args.level:
|
||||
if diff.added_levels or diff.removed_levels or \
|
||||
diff.modified_levels or args.level:
|
||||
print("Levels ({0} Added, {1} Removed, {2} Modified)".format(
|
||||
len(diff.added_levels), len(diff.removed_levels),
|
||||
len(diff.modified_levels)))
|
||||
if diff.added_levels and not args.stats:
|
||||
print(" Added Levels: {0}".format(len(diff.added_levels)))
|
||||
for l in sorted(diff.added_levels):
|
||||
print(" + {0}".format(l))
|
||||
if diff.removed_levels and not args.stats:
|
||||
print(" Removed Levels: {0}".format(len(diff.removed_levels)))
|
||||
for l in sorted(diff.removed_levels):
|
||||
print(" - {0}".format(l))
|
||||
if diff.modified_levels and not args.stats:
|
||||
print(" Modified Levels: {0}".format(len(diff.modified_levels)))
|
||||
for level, added_categories, removed_categories, _ in sorted(diff.modified_levels):
|
||||
change = []
|
||||
if added_categories:
|
||||
change.append("{0} Added Categories".format(len(added_categories)))
|
||||
if removed_categories:
|
||||
change.append("{0} Removed Categories".format(len(removed_categories)))
|
||||
|
||||
print(" * {0} ({1})".format(level.sensitivity, ", ".join(change)))
|
||||
for c in sorted(added_categories):
|
||||
print(" + {0}".format(c))
|
||||
for c in sorted(removed_categories):
|
||||
print(" - {0}".format(c))
|
||||
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(
|
||||
|
@ -21,7 +21,7 @@ from .commons import CommonDifference
|
||||
from .fsuse import FSUsesDifference
|
||||
from .genfscon import GenfsconsDifference
|
||||
from .initsid import InitialSIDsDifference
|
||||
from .mls import CategoriesDifference, SensitivitiesDifference
|
||||
from .mls import CategoriesDifference, LevelDeclsDifference, SensitivitiesDifference
|
||||
from .mlsrules import MLSRulesDifference
|
||||
from .objclass import ObjClassDifference
|
||||
from .rbacrules import RBACRulesDifference
|
||||
@ -40,6 +40,7 @@ class PolicyDifference(BooleansDifference,
|
||||
FSUsesDifference,
|
||||
GenfsconsDifference,
|
||||
InitialSIDsDifference,
|
||||
LevelDeclsDifference,
|
||||
MLSRulesDifference,
|
||||
ObjClassDifference,
|
||||
RBACRulesDifference,
|
||||
|
@ -29,6 +29,11 @@ modified_sens_record = namedtuple("modified_sensitivity", ["added_aliases",
|
||||
"removed_aliases",
|
||||
"matched_aliases"])
|
||||
|
||||
modified_level_record = namedtuple("modified_level", ["level",
|
||||
"added_categories",
|
||||
"removed_categories",
|
||||
"matched_categories"])
|
||||
|
||||
|
||||
class CategoriesDifference(Difference):
|
||||
|
||||
@ -116,6 +121,71 @@ class SensitivitiesDifference(Difference):
|
||||
self.modified_sensitivities = None
|
||||
|
||||
|
||||
class LevelDeclsDifference(Difference):
|
||||
|
||||
"""Determine the difference in levels between two policies."""
|
||||
|
||||
added_levels = DiffResultDescriptor("diff_levels")
|
||||
removed_levels = DiffResultDescriptor("diff_levels")
|
||||
modified_levels = DiffResultDescriptor("diff_levels")
|
||||
|
||||
def diff_levels(self):
|
||||
"""Generate the difference in levels between the policies."""
|
||||
|
||||
self.log.info(
|
||||
"Generating level decl differences from {0.left_policy} to {0.right_policy}".
|
||||
format(self))
|
||||
|
||||
self.added_levels, self.removed_levels, matched_levels = \
|
||||
self._set_diff(
|
||||
(LevelDeclWrapper(s) for s in self.left_policy.levels()),
|
||||
(LevelDeclWrapper(s) for s in self.right_policy.levels()))
|
||||
|
||||
self.modified_levels = []
|
||||
|
||||
for left_level, right_level in matched_levels:
|
||||
# Criteria for modified levels
|
||||
# 1. change to allowed categories
|
||||
added_categories, removed_categories, matched_categories = self._set_diff(
|
||||
(SymbolWrapper(c) for c in left_level.categories()),
|
||||
(SymbolWrapper(c) for c in right_level.categories()))
|
||||
|
||||
if added_categories or removed_categories:
|
||||
self.modified_levels.append(modified_level_record(
|
||||
left_level, added_categories, removed_categories, matched_categories))
|
||||
|
||||
#
|
||||
# Internal functions
|
||||
#
|
||||
def _reset_diff(self):
|
||||
"""Reset diff results on policy changes."""
|
||||
self.log.debug("Resetting sensitivity differences")
|
||||
self.added_levels = None
|
||||
self.removed_levels = None
|
||||
self.modified_levels = None
|
||||
|
||||
|
||||
class LevelDeclWrapper(Wrapper):
|
||||
|
||||
"""Wrap level declarations to allow comparisons."""
|
||||
|
||||
def __init__(self, level):
|
||||
self.origin = level
|
||||
self.sensitivity = SymbolWrapper(level.sensitivity)
|
||||
self.key = hash(level)
|
||||
|
||||
def __hash__(self):
|
||||
return self.key
|
||||
|
||||
def __eq__(self, other):
|
||||
# non-MLS policies have no level declarations so there
|
||||
# should be no AttributeError possiblity here
|
||||
return self.sensitivity == other.sensitivity
|
||||
|
||||
def __lt__(self, other):
|
||||
return self.sensitivity < other.sensitivity
|
||||
|
||||
|
||||
class LevelWrapper(Wrapper):
|
||||
|
||||
"""Wrap levels to allow comparisons."""
|
||||
|
@ -1071,6 +1071,36 @@ class PolicyDifferenceTest(ValidateRule, unittest.TestCase):
|
||||
self.assertEqual("added_user:object_r:system:s0", added_context)
|
||||
self.assertEqual("removed_user:object_r:system:s0", removed_context)
|
||||
|
||||
#
|
||||
# level decl
|
||||
#
|
||||
def test_added_levels(self):
|
||||
"""Diff: added levels."""
|
||||
l = sorted(self.diff.added_levels)
|
||||
self.assertEqual(1, len(l))
|
||||
self.assertEqual("s46:c0.c4", l[0])
|
||||
|
||||
def test_removed_levels(self):
|
||||
"""Diff: removed levels."""
|
||||
l = sorted(self.diff.removed_levels)
|
||||
self.assertEqual(1, len(l))
|
||||
self.assertEqual("s47:c0.c4", l[0])
|
||||
|
||||
def test_modified_levels(self):
|
||||
"""Diff: modified levels."""
|
||||
l = sorted(self.diff.modified_levels)
|
||||
self.assertEqual(2, len(l))
|
||||
|
||||
level = l[0]
|
||||
self.assertEqual("s40", level.level.sensitivity)
|
||||
self.assertSetEqual(set(["c3"]), level.added_categories)
|
||||
self.assertFalse(level.removed_categories)
|
||||
|
||||
level = l[1]
|
||||
self.assertEqual("s41", level.level.sensitivity)
|
||||
self.assertFalse(level.added_categories)
|
||||
self.assertSetEqual(set(["c4"]), level.removed_categories)
|
||||
|
||||
|
||||
class PolicyDifferenceTestNoDiff(unittest.TestCase):
|
||||
|
||||
@ -1343,3 +1373,15 @@ class PolicyDifferenceTestNoDiff(unittest.TestCase):
|
||||
def test_modified_genfscons(self):
|
||||
"""NoDiff: no modified genfscons."""
|
||||
self.assertFalse(self.diff.modified_genfscons)
|
||||
|
||||
def test_added_levels(self):
|
||||
"""NoDiff: no added levels."""
|
||||
self.assertFalse(self.diff.added_levels)
|
||||
|
||||
def test_removed_levels(self):
|
||||
"""NoDiff: no removed levels."""
|
||||
self.assertFalse(self.diff.removed_levels)
|
||||
|
||||
def test_modified_levels(self):
|
||||
"""NoDiff: no modified levels."""
|
||||
self.assertFalse(self.diff.modified_levels)
|
||||
|
@ -121,7 +121,7 @@ level s0:c0.c4;
|
||||
level s1:c0.c4;
|
||||
level s2:c0.c4;
|
||||
level s3:c0.c4;
|
||||
level s40:c0.c4;
|
||||
level s40:c1;
|
||||
level s41:c0.c4;
|
||||
level s42:c0.c4;
|
||||
level s43:c0.c4;
|
||||
|
@ -121,8 +121,8 @@ level s0:c0.c4;
|
||||
level s1:c0.c4;
|
||||
level s2:c0.c4;
|
||||
level s3:c0.c4;
|
||||
level s40:c0.c4;
|
||||
level s41:c0.c4;
|
||||
level s40:c1,c3;
|
||||
level s41:c0.c3;
|
||||
level s42:c0.c4;
|
||||
level s43:c0.c4;
|
||||
level s44:c0.c4;
|
||||
|
Loading…
Reference in New Issue
Block a user