PolicyDifference: implement genfscon diff

Closes #41
This commit is contained in:
Chris PeBenito 2016-01-11 14:43:11 -05:00
parent ee1c0b3328
commit afeb3561d2
6 changed files with 178 additions and 0 deletions

22
sediff
View File

@ -789,6 +789,28 @@ try:
print() print()
if all_differences or args.genfscon:
if diff.added_genfscons or diff.removed_genfscons or diff.modified_genfscons \
or args.genfscon:
print("Genfscons ({0} Added, {1} Removed, {2} Modified)".format(
len(diff.added_genfscons), len(diff.removed_genfscons),
len(diff.modified_genfscons)))
if diff.added_genfscons and not args.stats:
print(" Added Genfscons: {0}".format(len(diff.added_genfscons)))
for s in sorted(diff.added_genfscons):
print(" + {0}".format(s))
if diff.removed_genfscons and not args.stats:
print(" Removed Genfscons: {0}".format(len(diff.removed_genfscons)))
for s in sorted(diff.removed_genfscons):
print(" - {0}".format(s))
if diff.modified_genfscons and not args.stats:
print(" Modified Genfscons: {0}".format(len(diff.modified_genfscons)))
for entry in sorted(diff.modified_genfscons):
print(" * genfscon {0.fs} {0.path} {0.filetype} +[{1}] -[{2}];".format(
entry.rule, entry.added_context, entry.removed_context))
print()
except Exception as err: except Exception as err:
if args.debug: if args.debug:
import traceback import traceback

View File

@ -19,6 +19,7 @@
from .bool import BooleansDifference from .bool import BooleansDifference
from .commons import CommonDifference from .commons import CommonDifference
from .fsuse import FSUsesDifference from .fsuse import FSUsesDifference
from .genfscon import GenfsconsDifference
from .initsid import InitialSIDsDifference from .initsid import InitialSIDsDifference
from .mls import CategoriesDifference, SensitivitiesDifference from .mls import CategoriesDifference, SensitivitiesDifference
from .mlsrules import MLSRulesDifference from .mlsrules import MLSRulesDifference
@ -37,6 +38,7 @@ class PolicyDifference(BooleansDifference,
CategoriesDifference, CategoriesDifference,
CommonDifference, CommonDifference,
FSUsesDifference, FSUsesDifference,
GenfsconsDifference,
InitialSIDsDifference, InitialSIDsDifference,
MLSRulesDifference, MLSRulesDifference,
ObjClassDifference, ObjClassDifference,

92
setools/diff/genfscon.py Normal file
View File

@ -0,0 +1,92 @@
# 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 .context import ContextWrapper
from .descriptors import DiffResultDescriptor
from .difference import Difference, Wrapper
modified_genfs_record = namedtuple("modified_genfs", ["rule",
"added_context",
"removed_context"])
class GenfsconsDifference(Difference):
"""Determine the difference in genfscon rules between two policies."""
added_genfscons = DiffResultDescriptor("diff_genfscons")
removed_genfscons = DiffResultDescriptor("diff_genfscons")
modified_genfscons = DiffResultDescriptor("diff_genfscons")
def diff_genfscons(self):
"""Generate the difference in genfscon rules between the policies."""
self.log.info(
"Generating genfscon differences from {0.left_policy} to {0.right_policy}".
format(self))
self.added_genfscons, self.removed_genfscons, matched = self._set_diff(
(GenfsconWrapper(fs) for fs in self.left_policy.genfscons()),
(GenfsconWrapper(fs) for fs in self.right_policy.genfscons()))
self.modified_genfscons = []
for left_rule, right_rule in matched:
# Criteria for modified rules
# 1. change to context
if ContextWrapper(left_rule.context) != ContextWrapper(right_rule.context):
self.modified_genfscons.append(modified_genfs_record(left_rule,
right_rule.context,
left_rule.context))
#
# Internal functions
#
def _reset_diff(self):
"""Reset diff results on policy changes."""
self.log.debug("Resetting genfscon rule differences")
self.added_genfscons = None
self.removed_genfscons = None
self.modified_genfscons = None
class GenfsconWrapper(Wrapper):
"""Wrap genfscon rules to allow set operations."""
def __init__(self, rule):
self.origin = rule
self.fs = rule.fs
self.path = rule.path
self.filetype = rule.filetype
self.context = ContextWrapper(rule.context)
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.fs == other.fs and \
self.path == other.path and \
self.filetype == other.filetype

View File

@ -1027,6 +1027,50 @@ class PolicyDifferenceTest(ValidateRule, unittest.TestCase):
self.assertEqual("added_user:object_r:system:s1", added_context) self.assertEqual("added_user:object_r:system:s1", added_context)
self.assertEqual("removed_user:object_r:system:s0", removed_context) self.assertEqual("removed_user:object_r:system:s0", removed_context)
#
# genfscon
#
def test_added_genfscons(self):
"""Diff: added genfscons."""
l = sorted(self.diff.added_genfscons)
self.assertEqual(2, len(l))
rule = l[0]
self.assertEqual("added_genfs", rule.fs)
self.assertEqual("/", rule.path)
self.assertEqual("added_user:object_r:system:s0", rule.context)
rule = l[1]
self.assertEqual("change_path", rule.fs)
self.assertEqual("/new", rule.path)
self.assertEqual("system:object_r:system:s0", rule.context)
def test_removed_genfscons(self):
"""Diff: removed genfscons."""
l = sorted(self.diff.removed_genfscons)
self.assertEqual(2, len(l))
rule = l[0]
self.assertEqual("change_path", rule.fs)
self.assertEqual("/old", rule.path)
self.assertEqual("system:object_r:system:s0", rule.context)
rule = l[1]
self.assertEqual("removed_genfs", rule.fs)
self.assertEqual("/", rule.path)
self.assertEqual("system:object_r:system:s0", rule.context)
def test_modified_genfscons(self):
"""Diff: modified genfscons."""
l = sorted(self.diff.modified_genfscons)
self.assertEqual(1, len(l))
rule, added_context, removed_context = l[0]
self.assertEqual("modified_genfs", rule.fs)
self.assertEqual("/", rule.path)
self.assertEqual("added_user:object_r:system:s0", added_context)
self.assertEqual("removed_user:object_r:system:s0", removed_context)
class PolicyDifferenceTestNoDiff(unittest.TestCase): class PolicyDifferenceTestNoDiff(unittest.TestCase):
@ -1287,3 +1331,15 @@ class PolicyDifferenceTestNoDiff(unittest.TestCase):
def test_modified_fs_uses(self): def test_modified_fs_uses(self):
"""NoDiff: no modified fs_uses.""" """NoDiff: no modified fs_uses."""
self.assertFalse(self.diff.modified_fs_uses) self.assertFalse(self.diff.modified_fs_uses)
def test_added_genfscons(self):
"""NoDiff: no added genfscons."""
self.assertFalse(self.diff.added_genfscons)
def test_removed_genfscons(self):
"""NoDiff: no removed genfscons."""
self.assertFalse(self.diff.removed_genfscons)
def test_modified_genfscons(self):
"""NoDiff: no modified genfscons."""
self.assertFalse(self.diff.modified_genfscons)

View File

@ -626,6 +626,9 @@ fs_use_trans modified_fsuse removed_user:object_r:system:s0;
genfscon proc / system:object_r:system:s0 genfscon proc / system:object_r:system:s0
genfscon proc /sys system:object_r:system:s0 genfscon proc /sys system:object_r:system:s0
genfscon selinuxfs / system:object_r:system:s0 genfscon selinuxfs / system:object_r:system:s0
genfscon removed_genfs / system:object_r:system:s0
genfscon change_path /old system:object_r:system:s0
genfscon modified_genfs / -s removed_user:object_r:system:s0
portcon tcp 80 system:object_r:system:s0 portcon tcp 80 system:object_r:system:s0

View File

@ -626,6 +626,9 @@ fs_use_trans modified_fsuse added_user:object_r:system:s1;
genfscon proc / system:object_r:system:s0 genfscon proc / system:object_r:system:s0
genfscon proc /sys system:object_r:system:s0 genfscon proc /sys system:object_r:system:s0
genfscon selinuxfs / system:object_r:system:s0 genfscon selinuxfs / system:object_r:system:s0
genfscon added_genfs / added_user:object_r:system:s0
genfscon change_path /new system:object_r:system:s0
genfscon modified_genfs / -s added_user:object_r:system:s0
portcon tcp 80 system:object_r:system:s0 portcon tcp 80 system:object_r:system:s0