mirror of
https://github.com/SELinuxProject/setools
synced 2025-02-21 22:46:50 +00:00
parent
699ce33cd7
commit
a4d4920d3c
25
sediff
25
sediff
@ -91,6 +91,7 @@ other.add_argument("--default", action="store_true", help="Print default_* diffe
|
||||
other.add_argument("--property", action="store_true",
|
||||
help="Print policy property differences (handle_unknown, version, MLS)")
|
||||
other.add_argument("--polcap", action="store_true", help="Print policy capability differences")
|
||||
other.add_argument("--typebounds", action="store_true", help="Print typebounds differences")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
@ -101,7 +102,7 @@ all_differences = not any((args.class_, args.common, args.type_, args.attribute,
|
||||
args.role_trans, args.range_trans, args.initialsid, args.genfscon,
|
||||
args.netifcon, args.nodecon, args.portcon, args.fs_use, args.polcap,
|
||||
args.property, args.default, args.constrain, args.mlsconstrain,
|
||||
args.validatetrans, args.mlsvalidatetrans))
|
||||
args.validatetrans, args.mlsvalidatetrans, args.typebounds))
|
||||
|
||||
if args.debug:
|
||||
logging.basicConfig(level=logging.DEBUG,
|
||||
@ -1087,6 +1088,28 @@ try:
|
||||
|
||||
print()
|
||||
|
||||
if all_differences or args.typebounds:
|
||||
if diff.added_typebounds or diff.removed_typebounds or args.typebounds:
|
||||
print("Typebounds ({0} Added, {1} Removed, {2} Modified)".format(
|
||||
len(diff.added_typebounds), len(diff.removed_typebounds),
|
||||
len(diff.modified_typebounds)))
|
||||
if diff.added_typebounds and not args.stats:
|
||||
print(" Added Typebounds: {0}".format(len(diff.added_typebounds)))
|
||||
for d in sorted(diff.added_typebounds):
|
||||
print(" + {0}".format(d))
|
||||
if diff.removed_typebounds and not args.stats:
|
||||
print(" Removed Typebounds: {0}".format(len(diff.removed_typebounds)))
|
||||
for d in sorted(diff.removed_typebounds):
|
||||
print(" - {0}".format(d))
|
||||
if diff.modified_typebounds and not args.stats:
|
||||
print(" Modified Typebounds: {0}".format(len(diff.modified_typebounds)))
|
||||
for bound, added_bound, removed_bound in sorted(
|
||||
diff.modified_typebounds, key=lambda x: x.rule):
|
||||
print(" * {0.ruletype} +{1} -{2} {0.child};".format(
|
||||
bound, added_bound, removed_bound))
|
||||
|
||||
print()
|
||||
|
||||
except Exception as err:
|
||||
if args.debug:
|
||||
import traceback
|
||||
|
@ -17,6 +17,7 @@
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from .bool import BooleansDifference
|
||||
from .bounds import BoundsDifference
|
||||
from .commons import CommonDifference
|
||||
from .constraints import ConstraintsDifference
|
||||
from .default import DefaultsDifference
|
||||
@ -42,6 +43,7 @@ __all__ = ['PolicyDifference']
|
||||
|
||||
|
||||
class PolicyDifference(BooleansDifference,
|
||||
BoundsDifference,
|
||||
CategoriesDifference,
|
||||
CommonDifference,
|
||||
ConstraintsDifference,
|
||||
|
112
setools/diff/bounds.py
Normal file
112
setools/diff/bounds.py
Normal file
@ -0,0 +1,112 @@
|
||||
# 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, Wrapper
|
||||
|
||||
|
||||
modified_bounds_record = namedtuple("modified_bound", ["rule", "added_bound", "removed_bound"])
|
||||
|
||||
|
||||
class BoundsDifference(Difference):
|
||||
|
||||
"""Determine the difference in *bounds between two policies."""
|
||||
|
||||
added_typebounds = DiffResultDescriptor("diff_typebounds")
|
||||
removed_typebounds = DiffResultDescriptor("diff_typebounds")
|
||||
modified_typebounds = DiffResultDescriptor("diff_typebounds")
|
||||
|
||||
# Lists of rules for each policy
|
||||
_left_typebounds = None
|
||||
_right_typebounds = None
|
||||
|
||||
def diff_typebounds(self):
|
||||
"""Generate the difference in typebound rules between the policies."""
|
||||
|
||||
self.log.info("Generating typebounds differences from {0.left_policy} to {0.right_policy}".
|
||||
format(self))
|
||||
|
||||
if self._left_typebounds is None or self._right_typebounds is None:
|
||||
self._create_typebound_lists()
|
||||
|
||||
self.added_typebounds, self.removed_typebounds, matched_typebounds = self._set_diff(
|
||||
(BoundsWrapper(c) for c in self._left_typebounds),
|
||||
(BoundsWrapper(c) for c in self._right_typebounds),
|
||||
key=lambda b: str(b.child))
|
||||
|
||||
self.modified_typebounds = []
|
||||
|
||||
for left_bound, right_bound in matched_typebounds:
|
||||
if SymbolWrapper(left_bound.parent) != SymbolWrapper(right_bound.parent):
|
||||
self.modified_typebounds.append(modified_bounds_record(
|
||||
left_bound, right_bound.parent, left_bound.parent))
|
||||
|
||||
#
|
||||
# Internal functions
|
||||
#
|
||||
def _create_typebound_lists(self):
|
||||
"""Create rule lists for both policies."""
|
||||
self._left_typebounds = []
|
||||
for rule in self.left_policy.bounds():
|
||||
if rule.ruletype == "typebounds":
|
||||
self._left_typebounds.append(rule)
|
||||
else:
|
||||
self.log.error("Unknown rule type: {0} (This is an SETools bug)".
|
||||
format(rule.ruletype))
|
||||
|
||||
self._right_typebounds = []
|
||||
for rule in self.right_policy.bounds():
|
||||
if rule.ruletype == "typebounds":
|
||||
self._right_typebounds.append(rule)
|
||||
else:
|
||||
self.log.error("Unknown rule type: {0} (This is an SETools bug)".
|
||||
format(rule.ruletype))
|
||||
|
||||
def _reset_diff(self):
|
||||
"""Reset diff results on policy changes."""
|
||||
self.log.debug("Resetting all *bounds differences")
|
||||
self.added_typebounds = None
|
||||
self.removed_typebounds = None
|
||||
|
||||
# Sets of rules for each policy
|
||||
self._left_typebounds = None
|
||||
self._right_typebounds = None
|
||||
|
||||
|
||||
class BoundsWrapper(Wrapper):
|
||||
|
||||
"""Wrap *bounds for diff purposes."""
|
||||
|
||||
def __init__(self, rule):
|
||||
self.origin = rule
|
||||
self.ruletype = rule.ruletype
|
||||
self.parent = SymbolWrapper(rule.parent)
|
||||
self.child = SymbolWrapper(rule.child)
|
||||
self.key = hash(rule)
|
||||
|
||||
def __hash__(self):
|
||||
return self.key
|
||||
|
||||
def __lt__(self, other):
|
||||
return self.key < other.key
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.ruletype == other.ruletype and \
|
||||
self.child == other.child
|
@ -72,7 +72,7 @@ class Difference(object):
|
||||
yield Wrapper(expanded_rule)
|
||||
|
||||
@staticmethod
|
||||
def _set_diff(left, right):
|
||||
def _set_diff(left, right, key=None):
|
||||
"""
|
||||
Standard diff of two sets.
|
||||
|
||||
@ -108,8 +108,8 @@ class Difference(object):
|
||||
# instead of giving wrong results. If there is a better way to,
|
||||
# ensure the items match up, please let me know how or submit a patch.
|
||||
matched_items = set()
|
||||
left_matched_items = sorted((left_items - removed_items))
|
||||
right_matched_items = sorted((right_items - added_items))
|
||||
left_matched_items = sorted((left_items - removed_items), key=key)
|
||||
right_matched_items = sorted((right_items - added_items), key=key)
|
||||
assert len(left_matched_items) == len(right_matched_items), \
|
||||
"Matched items assertion failure (this is an SETools bug), {0} != {1}". \
|
||||
format(len(left_matched_items), len(right_matched_items))
|
||||
|
@ -37,6 +37,9 @@ class Bounds(PolicySymbol):
|
||||
def __str__(self):
|
||||
return "{0.ruletype} {0.parent} {0.child};".format(self)
|
||||
|
||||
def __hash__(self):
|
||||
return hash("{0.ruletype}|{0.child};".format(self))
|
||||
|
||||
ruletype = "typebounds"
|
||||
|
||||
@property
|
||||
|
@ -1521,6 +1521,40 @@ class PolicyDifferenceTest(ValidateRule, unittest.TestCase):
|
||||
['l1', 'l2', 'dom', 'h1', 'h2', 'dom', 'and', 't3', set(["mls_exempt"]), '==', 'or'],
|
||||
mlsvalidatetrans.postfix_expression())
|
||||
|
||||
#
|
||||
# typebounds
|
||||
#
|
||||
def test_added_typebounds(self):
|
||||
"""Diff: added typebounds."""
|
||||
l = sorted(self.diff.added_typebounds)
|
||||
self.assertEqual(1, len(l))
|
||||
|
||||
bounds = l[0]
|
||||
self.assertEqual("typebounds", bounds.ruletype)
|
||||
self.assertEqual("added_parent", bounds.parent)
|
||||
self.assertEqual("added_child", bounds.child)
|
||||
|
||||
def test_removed_typebounds(self):
|
||||
"""Diff: removed typebounds."""
|
||||
l = sorted(self.diff.removed_typebounds)
|
||||
self.assertEqual(1, len(l))
|
||||
|
||||
bounds = l[0]
|
||||
self.assertEqual("typebounds", bounds.ruletype)
|
||||
self.assertEqual("removed_parent", bounds.parent)
|
||||
self.assertEqual("removed_child", bounds.child)
|
||||
|
||||
def test_modified_typebounds(self):
|
||||
"""Diff: modified typebounds."""
|
||||
l = sorted(self.diff.modified_typebounds, key=lambda x: x.rule)
|
||||
self.assertEqual(1, len(l))
|
||||
|
||||
bounds, added_bound, removed_bound = l[0]
|
||||
self.assertEqual("typebounds", bounds.ruletype)
|
||||
self.assertEqual("mod_child", bounds.child)
|
||||
self.assertEqual("mod_parent_added", added_bound)
|
||||
self.assertEqual("mod_parent_removed", removed_bound)
|
||||
|
||||
|
||||
class PolicyDifferenceTestNoDiff(unittest.TestCase):
|
||||
|
||||
@ -1899,6 +1933,18 @@ class PolicyDifferenceTestNoDiff(unittest.TestCase):
|
||||
"""NoDiff: no removed mlsvalidatetrans."""
|
||||
self.assertFalse(self.diff.removed_mlsvalidatetrans)
|
||||
|
||||
def test_added_typebounds(self):
|
||||
"""NoDiff: no added typebounds."""
|
||||
self.assertFalse(self.diff.added_typebounds)
|
||||
|
||||
def test_removed_typebounds(self):
|
||||
"""NoDiff: no removed typebounds."""
|
||||
self.assertFalse(self.diff.removed_typebounds)
|
||||
|
||||
def test_modified_typebounds(self):
|
||||
"""NoDiff: no modified typebounds."""
|
||||
self.assertFalse(self.diff.modified_typebounds)
|
||||
|
||||
|
||||
class PolicyDifferenceTestMLStoStandard(unittest.TestCase):
|
||||
|
||||
@ -2294,3 +2340,15 @@ class PolicyDifferenceTestMLStoStandard(unittest.TestCase):
|
||||
self.assertEqual(
|
||||
sum(1 for m in self.diff.left_policy.constraints() if m.ruletype == "mlsvalidatetrans"),
|
||||
len(self.diff.removed_mlsvalidatetrans))
|
||||
|
||||
def test_added_typebounds(self):
|
||||
"""MLSvsStandardDiff: no added typebounds."""
|
||||
self.assertFalse(self.diff.added_typebounds)
|
||||
|
||||
def test_removed_typebounds(self):
|
||||
"""MLSvsStandardDiff: no removed typebounds."""
|
||||
self.assertFalse(self.diff.removed_typebounds)
|
||||
|
||||
def test_modified_typebounds(self):
|
||||
"""MLSvsStandardDiff: no modified typebounds."""
|
||||
self.assertFalse(self.diff.modified_typebounds)
|
||||
|
@ -635,6 +635,25 @@ role role_tr_new_role;
|
||||
role_transition role_tr_matched_source role_tr_matched_target:infoflow3 role_tr_old_role;
|
||||
|
||||
################################################################################
|
||||
# matching typebounds
|
||||
type match_parent;
|
||||
type match_child;
|
||||
typebounds match_parent match_child;
|
||||
|
||||
# removed typebounds
|
||||
type removed_parent;
|
||||
type removed_child;
|
||||
typebounds removed_parent removed_child;
|
||||
|
||||
# added typebounds
|
||||
type added_parent;
|
||||
type added_child;
|
||||
|
||||
# modified typebounds
|
||||
type mod_parent_removed;
|
||||
type mod_parent_added;
|
||||
type mod_child;
|
||||
typebounds mod_parent_removed mod_child;
|
||||
|
||||
# policycaps
|
||||
policycap open_perms;
|
||||
|
@ -557,6 +557,25 @@ role role_tr_new_role;
|
||||
role_transition role_tr_matched_source role_tr_matched_target:infoflow3 role_tr_old_role;
|
||||
|
||||
################################################################################
|
||||
# matching typebounds
|
||||
type match_parent;
|
||||
type match_child;
|
||||
typebounds match_parent match_child;
|
||||
|
||||
# removed typebounds
|
||||
type removed_parent;
|
||||
type removed_child;
|
||||
typebounds removed_parent removed_child;
|
||||
|
||||
# added typebounds
|
||||
type added_parent;
|
||||
type added_child;
|
||||
|
||||
# modified typebounds
|
||||
type mod_parent_removed;
|
||||
type mod_parent_added;
|
||||
type mod_child;
|
||||
typebounds mod_parent_removed mod_child;
|
||||
|
||||
# policycaps
|
||||
policycap open_perms;
|
||||
|
@ -635,6 +635,25 @@ role role_tr_new_role;
|
||||
role_transition role_tr_matched_source role_tr_matched_target:infoflow3 role_tr_new_role;
|
||||
|
||||
################################################################################
|
||||
# matching typebounds
|
||||
type match_parent;
|
||||
type match_child;
|
||||
typebounds match_parent match_child;
|
||||
|
||||
# removed typebounds
|
||||
type removed_parent;
|
||||
type removed_child;
|
||||
|
||||
# added typebounds
|
||||
type added_parent;
|
||||
type added_child;
|
||||
typebounds added_parent added_child;
|
||||
|
||||
# modified typebounds
|
||||
type mod_parent_removed;
|
||||
type mod_parent_added;
|
||||
type mod_child;
|
||||
typebounds mod_parent_added mod_child;
|
||||
|
||||
# policycaps
|
||||
policycap open_perms;
|
||||
|
Loading…
Reference in New Issue
Block a user