mirror of
https://github.com/SELinuxProject/setools
synced 2025-03-11 07:18:15 +00:00
Implement included/excluded classes/permissions in PermissionMap.
closes #24
This commit is contained in:
parent
a6c3784f4d
commit
ceb6736962
13
README
13
README
@ -55,6 +55,19 @@ To run SETools, the following packages are required:
|
||||
libsepol 2.4+
|
||||
libbz2
|
||||
|
||||
To run SETools unit tests, the following packages are required:
|
||||
Python 2.7 or 3.3+
|
||||
setuptools
|
||||
gcc
|
||||
bison
|
||||
flex
|
||||
libselinux
|
||||
libsepol 2.4+
|
||||
libbz2
|
||||
SWIG 2.0.12+ or 3.0+
|
||||
mock (on Python 2.7 only)
|
||||
tox (optional)
|
||||
|
||||
2.1. building SETools
|
||||
---------------------
|
||||
|
||||
|
@ -19,6 +19,18 @@
|
||||
from . import policyrep
|
||||
|
||||
|
||||
class RuleTypeError(Exception):
|
||||
|
||||
"""Exception for using rules with incorrect rule type."""
|
||||
pass
|
||||
|
||||
|
||||
class UnmappedClass(Exception):
|
||||
|
||||
"""Exception for classes that are unmapped"""
|
||||
pass
|
||||
|
||||
|
||||
class UnmappedPermission(Exception):
|
||||
|
||||
"""Exception for permissions that are unmapped"""
|
||||
@ -135,6 +147,89 @@ class PermissionMap(object):
|
||||
if perm_count >= num_perms:
|
||||
state = 2
|
||||
|
||||
def exclude_class(self, class_):
|
||||
"""
|
||||
Exclude all permissions in an object class for calculating rule weights.
|
||||
|
||||
Parameter:
|
||||
class_ The object class to exclude.
|
||||
|
||||
Exceptions:
|
||||
UnmappedClass The specified object class is not mapped.
|
||||
"""
|
||||
|
||||
classname = str(class_)
|
||||
|
||||
try:
|
||||
for perm in self.permmap[classname]:
|
||||
self.permmap[classname][perm]['enabled'] = False
|
||||
except KeyError:
|
||||
raise UnmappedClass("{0} is not mapped.".format(classname))
|
||||
|
||||
def exclude_permission(self, class_, permission):
|
||||
"""
|
||||
Exclude a permission for calculating rule weights.
|
||||
|
||||
Parameter:
|
||||
class_ The object class of the permission.
|
||||
permission The permission name to exclude.
|
||||
|
||||
Exceptions:
|
||||
UnmappedClass The specified object class is not mapped.
|
||||
UnmappedPermission The specified permission is not mapped for the object class.
|
||||
"""
|
||||
classname = str(class_)
|
||||
|
||||
if classname not in self.permmap:
|
||||
raise UnmappedClass("{0} is not mapped.".format(classname))
|
||||
|
||||
try:
|
||||
self.permmap[classname][permission]['enabled'] = False
|
||||
except KeyError:
|
||||
raise UnmappedPermission("{0}:{1} is not mapped.".format(classname, permission))
|
||||
|
||||
def include_class(self, class_):
|
||||
"""
|
||||
Include all permissions in an object class for calculating rule weights.
|
||||
|
||||
Parameter:
|
||||
class_ The object class to include.
|
||||
|
||||
Exceptions:
|
||||
UnmappedClass The specified object class is not mapped.
|
||||
"""
|
||||
|
||||
classname = str(class_)
|
||||
|
||||
try:
|
||||
for perm in self.permmap[classname]:
|
||||
self.permmap[classname][perm]['enabled'] = True
|
||||
except KeyError:
|
||||
raise UnmappedClass("{0} is not mapped.".format(classname))
|
||||
|
||||
def include_permission(self, class_, permission):
|
||||
"""
|
||||
Include a permission for calculating rule weights.
|
||||
|
||||
Parameter:
|
||||
class_ The object class of the permission.
|
||||
permission The permission name to include.
|
||||
|
||||
Exceptions:
|
||||
UnmappedClass The specified object class is not mapped.
|
||||
UnmappedPermission The specified permission is not mapped for the object class.
|
||||
"""
|
||||
|
||||
classname = str(class_)
|
||||
|
||||
if classname not in self.permmap:
|
||||
raise UnmappedClass("{0} is not mapped.".format(classname))
|
||||
|
||||
try:
|
||||
self.permmap[classname][permission]['enabled'] = True
|
||||
except KeyError:
|
||||
raise UnmappedPermission("{0}:{1} is not mapped.".format(classname, permission))
|
||||
|
||||
def rule_weight(self, rule):
|
||||
"""
|
||||
Get the type enforcement rule's information flow read and write weights.
|
||||
@ -151,11 +246,21 @@ class PermissionMap(object):
|
||||
read_weight = 0
|
||||
class_name = str(rule.tclass)
|
||||
|
||||
if rule.ruletype != 'allow':
|
||||
raise RuleTypeError("{0} rules cannot be used for calculating a weight".
|
||||
format(rule.ruletype))
|
||||
|
||||
if class_name not in self.permmap:
|
||||
raise UnmappedClass("{0} is not mapped.".format(class_name))
|
||||
|
||||
# iterate over the permissions and determine the
|
||||
# weight of the rule in each direction. The result
|
||||
# is the largest-weight permission in each direction
|
||||
for perm_name in rule.perms:
|
||||
mapping = self.permmap[class_name][perm_name]
|
||||
try:
|
||||
mapping = self.permmap[class_name][perm_name]
|
||||
except KeyError:
|
||||
raise UnmappedPermission("{0}:{1} is not mapped.".format(class_name, perm_name))
|
||||
|
||||
if not mapping['enabled']:
|
||||
continue
|
||||
|
@ -25,6 +25,7 @@ from . import mlsrulequery
|
||||
from . import netifconquery
|
||||
from . import nodeconquery
|
||||
from . import objclassquery
|
||||
from . import permmap
|
||||
from . import polcapquery
|
||||
from . import infoflow
|
||||
from . import terulequery
|
||||
|
186
tests/permmap.py
Normal file
186
tests/permmap.py
Normal file
@ -0,0 +1,186 @@
|
||||
# Copyright 2015, 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 General Public License as published by
|
||||
# the Free Software Foundation, either version 2 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with SETools. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import unittest
|
||||
|
||||
try:
|
||||
from unittest.mock import MagicMock
|
||||
except ImportError:
|
||||
from mock import MagicMock
|
||||
|
||||
from setools import SELinuxPolicy
|
||||
from setools.permmap import PermissionMap, UnmappedClass, UnmappedPermission, RuleTypeError
|
||||
|
||||
|
||||
class PermissionMapTest(unittest.TestCase):
|
||||
|
||||
def test_001_load(self):
|
||||
"""PermMap open from path."""
|
||||
permmap = PermissionMap("tests/perm_map")
|
||||
self.assertTrue(permmap)
|
||||
|
||||
# 100 get/set weight
|
||||
# 110 get/set direction
|
||||
|
||||
def test_120_exclude_perm(self):
|
||||
"""PermMap exclude permission."""
|
||||
|
||||
permmap = PermissionMap("tests/perm_map")
|
||||
permmap.exclude_permission("infoflow", "med_w")
|
||||
self.assertFalse(permmap.permmap['infoflow']['med_w']['enabled'])
|
||||
|
||||
def test_121_reinclude_perm(self):
|
||||
"""PermMap include permission."""
|
||||
|
||||
permmap = PermissionMap("tests/perm_map")
|
||||
permmap.exclude_permission("infoflow", "med_w")
|
||||
self.assertFalse(permmap.permmap['infoflow']['med_w']['enabled'])
|
||||
|
||||
permmap.include_permission("infoflow", "med_w")
|
||||
self.assertTrue(permmap.permmap['infoflow']['med_w']['enabled'])
|
||||
|
||||
def test_122_exclude_class(self):
|
||||
"""PermMap exclude class."""
|
||||
|
||||
permmap = PermissionMap("tests/perm_map")
|
||||
permmap.exclude_class("file")
|
||||
self.assertFalse(permmap.permmap['file']['execute']['enabled'])
|
||||
self.assertFalse(permmap.permmap['file']['entrypoint']['enabled'])
|
||||
|
||||
def test_123_include_class(self):
|
||||
"""PermMap exclude class."""
|
||||
|
||||
permmap = PermissionMap("tests/perm_map")
|
||||
permmap.exclude_class("file")
|
||||
self.assertFalse(permmap.permmap['file']['execute']['enabled'])
|
||||
self.assertFalse(permmap.permmap['file']['entrypoint']['enabled'])
|
||||
|
||||
permmap.include_class("file")
|
||||
self.assertTrue(permmap.permmap['file']['execute']['enabled'])
|
||||
self.assertTrue(permmap.permmap['file']['entrypoint']['enabled'])
|
||||
|
||||
def test_130_weight_read_only(self):
|
||||
"""PermMap get weight of read-only rule."""
|
||||
|
||||
rule = MagicMock()
|
||||
rule.ruletype = "allow"
|
||||
rule.tclass = "infoflow"
|
||||
rule.perms = set(["med_r", "hi_r"])
|
||||
|
||||
permmap = PermissionMap("tests/perm_map")
|
||||
r, w = permmap.rule_weight(rule)
|
||||
self.assertEqual(r, 10)
|
||||
self.assertEqual(w, 0)
|
||||
|
||||
def test_131_weight_write_only(self):
|
||||
"""PermMap get weight of write-only rule."""
|
||||
|
||||
rule = MagicMock()
|
||||
rule.ruletype = "allow"
|
||||
rule.tclass = "infoflow"
|
||||
rule.perms = set(["low_w", "med_w"])
|
||||
|
||||
permmap = PermissionMap("tests/perm_map")
|
||||
r, w = permmap.rule_weight(rule)
|
||||
self.assertEqual(r, 0)
|
||||
self.assertEqual(w, 5)
|
||||
|
||||
def test_132_weight_both(self):
|
||||
"""PermMap get weight of both rule."""
|
||||
|
||||
rule = MagicMock()
|
||||
rule.ruletype = "allow"
|
||||
rule.tclass = "infoflow"
|
||||
rule.perms = set(["low_r", "hi_w"])
|
||||
|
||||
permmap = PermissionMap("tests/perm_map")
|
||||
r, w = permmap.rule_weight(rule)
|
||||
self.assertEqual(r, 1)
|
||||
self.assertEqual(w, 10)
|
||||
|
||||
def test_133_weight_none(self):
|
||||
"""PermMap get weight of none rule."""
|
||||
|
||||
rule = MagicMock()
|
||||
rule.ruletype = "allow"
|
||||
rule.tclass = "infoflow3"
|
||||
rule.perms = set(["null"])
|
||||
|
||||
permmap = PermissionMap("tests/perm_map")
|
||||
r, w = permmap.rule_weight(rule)
|
||||
self.assertEqual(r, 0)
|
||||
self.assertEqual(w, 0)
|
||||
|
||||
def test_134_weight_unmapped_class(self):
|
||||
"""PermMap get weight of rule with unmapped class."""
|
||||
|
||||
rule = MagicMock()
|
||||
rule.ruletype = "allow"
|
||||
rule.tclass = "unmapped"
|
||||
rule.perms = set(["null"])
|
||||
|
||||
permmap = PermissionMap("tests/perm_map")
|
||||
self.assertRaises(UnmappedClass, permmap.rule_weight, rule)
|
||||
|
||||
def test_135_weight_unmapped_permission(self):
|
||||
"""PermMap get weight of rule with unmapped permission."""
|
||||
|
||||
rule = MagicMock()
|
||||
rule.ruletype = "allow"
|
||||
rule.tclass = "infoflow"
|
||||
rule.perms = set(["low_r", "unmapped"])
|
||||
|
||||
permmap = PermissionMap("tests/perm_map")
|
||||
self.assertRaises(UnmappedPermission, permmap.rule_weight, rule)
|
||||
|
||||
def test_136_weight_wrong_rule_type(self):
|
||||
"""PermMap get weight of rule with wrong rule type."""
|
||||
|
||||
rule = MagicMock()
|
||||
rule.ruletype = "type_transition"
|
||||
rule.tclass = "infoflow"
|
||||
|
||||
permmap = PermissionMap("tests/perm_map")
|
||||
self.assertRaises(RuleTypeError, permmap.rule_weight, rule)
|
||||
|
||||
def test_133_weight_excluded_permission(self):
|
||||
"""PermMap get weight of a rule with excluded permission."""
|
||||
|
||||
rule = MagicMock()
|
||||
rule.ruletype = "allow"
|
||||
rule.tclass = "infoflow"
|
||||
rule.perms = set(["med_r", "hi_r"])
|
||||
|
||||
permmap = PermissionMap("tests/perm_map")
|
||||
permmap.exclude_permission("infoflow", "hi_r")
|
||||
r, w = permmap.rule_weight(rule)
|
||||
self.assertEqual(r, 5)
|
||||
self.assertEqual(w, 0)
|
||||
|
||||
def test_133_weight_excluded_class(self):
|
||||
"""PermMap get weight of a rule with excluded class."""
|
||||
|
||||
rule = MagicMock()
|
||||
rule.ruletype = "allow"
|
||||
rule.tclass = "infoflow"
|
||||
rule.perms = set(["low_r", "med_r", "hi_r", "low_w", "med_w", "hi_w"])
|
||||
|
||||
permmap = PermissionMap("tests/perm_map")
|
||||
permmap.exclude_class("infoflow")
|
||||
r, w = permmap.rule_weight(rule)
|
||||
self.assertEqual(r, 0)
|
||||
self.assertEqual(w, 0)
|
Loading…
Reference in New Issue
Block a user