PolicyDifference: add type attribute diff

Closes #33
This commit is contained in:
Chris PeBenito 2016-01-08 11:25:13 -05:00
parent aebe3f8706
commit 451e549001
6 changed files with 135 additions and 0 deletions

30
sediff
View File

@ -225,6 +225,36 @@ try:
print()
if all_differences or args.attribute:
if diff.added_type_attributes or diff.removed_type_attributes or \
diff.modified_type_attributes or args.attribute:
print("Type Attributes ({0} Added, {1} Removed, {2} Modified)".format(
len(diff.added_type_attributes), len(diff.removed_type_attributes),
len(diff.modified_type_attributes)))
if diff.added_type_attributes and not args.stats:
print(" Added Type Attributes: {0}".format(len(diff.added_type_attributes)))
for a in sorted(diff.added_type_attributes):
print(" + {0}".format(a))
if diff.removed_type_attributes and not args.stats:
print(" Removed Type Attributes: {0}".format(len(diff.removed_type_attributes)))
for a in sorted(diff.removed_type_attributes):
print(" - {0}".format(a))
if diff.modified_type_attributes and not args.stats:
print(" Modified Type Attributes: {0}".format(len(diff.modified_type_attributes)))
for name, mod in sorted(diff.modified_type_attributes.items()):
change = []
if mod.added_types:
change.append("{0} Added types".format(len(mod.added_types)))
if mod.removed_types:
change.append("{0} Removed types".format(len(mod.removed_types)))
print(" * {0} ({1})".format(name, ", ".join(change)))
for t in sorted(mod.added_types):
print(" + {0}".format(t))
for t in sorted(mod.removed_types):
print(" - {0}".format(t))
print()
if all_differences or args.user:
if diff.added_users or diff.removed_users or diff.modified_users or args.user:
print("Users ({0} Added, {1} Removed, {2} Modified)".format(len(diff.added_users),

View File

@ -22,6 +22,7 @@ from .objclass import ObjClassDifference
from .rbacrules import RBACRulesDifference
from .roles import RolesDifference
from .terules import TERulesDifference
from .typeattr import TypeAttributesDifference
from .types import TypesDifference
from .users import UsersDifference
@ -34,6 +35,7 @@ class PolicyDifference(CommonDifference,
RBACRulesDifference,
RolesDifference,
TERulesDifference,
TypeAttributesDifference,
TypesDifference,
UsersDifference):

71
setools/diff/typeattr.py Normal file
View File

@ -0,0 +1,71 @@
# Copyright 2016, Tresys Technology, LLC
#
# This file is part of SETools.
#
# SETools is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation, either version 2.1 of
# the License, or (at your option) any later version.
#
# SETools is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with SETools. If not, see
# <http://www.gnu.org/licenses/>.
#
from collections import namedtuple
from .descriptors import DiffResultDescriptor
from .difference import Difference, SymbolWrapper
modified_typeattr_record = namedtuple("modified_typeattr", ["added_types",
"removed_types",
"matched_types"])
class TypeAttributesDifference(Difference):
"""Determine the difference in type attributes between two policies."""
added_type_attributes = DiffResultDescriptor("diff_type_attributes")
removed_type_attributes = DiffResultDescriptor("diff_type_attributes")
modified_type_attributes = DiffResultDescriptor("diff_type_attributes")
def diff_type_attributes(self):
"""Generate the difference in type attributes between the policies."""
self.log.info(
"Generating type attribute differences from {0.left_policy} to {0.right_policy}".
format(self))
self.added_type_attributes, self.removed_type_attributes, matched_attributes = \
self._set_diff(
(SymbolWrapper(r) for r in self.left_policy.typeattributes()),
(SymbolWrapper(r) for r in self.right_policy.typeattributes()))
self.modified_type_attributes = dict()
for left_attribute, right_attribute in matched_attributes:
# Criteria for modified attributes
# 1. change to type set
added_types, removed_types, matched_types = self._set_diff(
(SymbolWrapper(t) for t in left_attribute.expand()),
(SymbolWrapper(t) for t in right_attribute.expand()))
if added_types or removed_types:
self.modified_type_attributes[left_attribute] = modified_typeattr_record(
added_types, removed_types, matched_types)
#
# Internal functions
#
def _reset_diff(self):
"""Reset diff results on policy changes."""
self.log.debug("Resetting type attribute differences")
self.added_type_attributes = None
self.removed_type_attributes = None
self.modified_type_attributes = None

View File

@ -892,6 +892,24 @@ class PolicyDifferenceTest(ValidateRule, unittest.TestCase):
self.assertEqual("s3:c1.c4",
self.diff.modified_users["modified_change_range"].added_range)
#
# Type attributes
#
def test_added_type_attribute(self):
"""Diff: added type attribute."""
self.assertSetEqual(set(["added_attr"]), self.diff.added_type_attributes)
def test_removed_type_attribute(self):
"""Diff: removed type attribute."""
self.assertSetEqual(set(["removed_attr"]), self.diff.removed_type_attributes)
def test_modified_type_attribute(self):
"""Diff: modified type attribute."""
self.assertSetEqual(set(["modified_add_attr"]),
self.diff.modified_type_attributes["an_attr"].added_types)
self.assertSetEqual(set(["modified_remove_attr"]),
self.diff.modified_type_attributes["an_attr"].removed_types)
class PolicyDifferenceTestNoDiff(unittest.TestCase):
@ -1080,3 +1098,15 @@ class PolicyDifferenceTestNoDiff(unittest.TestCase):
def test_modified_users(self):
"""NoDiff: no modified user rules."""
self.assertFalse(self.diff.modified_users)
def test_added_type_attributes(self):
"""NoDiff: no added type attribute rules."""
self.assertFalse(self.diff.added_type_attributes)
def test_removed_type_attributes(self):
"""NoDiff: no removed type attribute rules."""
self.assertFalse(self.diff.removed_type_attributes)
def test_modified_type_attributes(self):
"""NoDiff: no modified type attribute rules."""
self.assertFalse(self.diff.modified_type_attributes)

View File

@ -130,6 +130,7 @@ mlsconstrain infoflow hi_r ((l1 dom l2) or (t1 == mls_exempt));
attribute mls_exempt;
attribute an_attr;
attribute removed_attr;
type system;
role system;

View File

@ -131,6 +131,7 @@ mlsconstrain infoflow hi_r ((l1 dom l2) or (t1 == mls_exempt));
attribute mls_exempt;
attribute an_attr;
attribute added_attr;
type system;
role system;