mirror of
https://github.com/SELinuxProject/setools
synced 2025-02-24 08:07:03 +00:00
Basic permission map implementation.
Drops sepolgen dependence.
This commit is contained in:
parent
43e9019193
commit
09eef20a5c
1
README
1
README
@ -42,7 +42,6 @@ To build SETools' graphical tools, the following packages are required:
|
|||||||
|
|
||||||
To run SETools, the following packages are required:
|
To run SETools, the following packages are required:
|
||||||
Python 2.7
|
Python 2.7
|
||||||
sepolgen
|
|
||||||
NetworkX
|
NetworkX
|
||||||
setuptools
|
setuptools
|
||||||
|
|
||||||
|
@ -16,27 +16,116 @@
|
|||||||
# License along with SETools. If not, see
|
# License along with SETools. If not, see
|
||||||
# <http://www.gnu.org/licenses/>.
|
# <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
|
from collections import defaultdict
|
||||||
from sepolgen import objectmodel as om
|
|
||||||
|
|
||||||
from . import policyrep
|
from . import policyrep
|
||||||
|
|
||||||
# build off of sepolgen perm map implementation
|
|
||||||
|
class UnmappedPermission(Exception):
|
||||||
|
|
||||||
|
"""Exception for permissions that are unmapped"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class PermissionMap(object, om.PermMappings):
|
class PermissionMap(object):
|
||||||
|
|
||||||
"""Permission Map for information flow analysis."""
|
"""Permission Map for information flow analysis."""
|
||||||
|
|
||||||
|
valid_infoflow_directions = ["r", "w", "b", "n", "u"]
|
||||||
|
min_weight = 1
|
||||||
|
max_weight = 10
|
||||||
|
|
||||||
def __init__(self, permmapfile="/usr/share/setools/perm_map"):
|
def __init__(self, permmapfile="/usr/share/setools/perm_map"):
|
||||||
"""
|
"""
|
||||||
Parameter:
|
Parameter:
|
||||||
permmapfile The path to the permission map to load.
|
permmapfile The path to the permission map to load.
|
||||||
"""
|
"""
|
||||||
|
self.load(permmapfile)
|
||||||
|
|
||||||
om.PermMappings.__init__(self)
|
def load(self, permmapfile):
|
||||||
|
"""
|
||||||
|
Parameter:
|
||||||
|
permmapfile The path to the permission map to load.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# state machine
|
||||||
|
# 1 = read number of classes
|
||||||
|
# 2 = read class name and number of perms
|
||||||
|
# 3 = read perms
|
||||||
with open(permmapfile, "r") as fd:
|
with open(permmapfile, "r") as fd:
|
||||||
self.from_file(fd)
|
class_count = 0
|
||||||
|
num_classes = 0
|
||||||
|
state = 1
|
||||||
|
|
||||||
|
self.permmap = defaultdict(lambda: defaultdict(lambda: ('u', 1)))
|
||||||
|
|
||||||
|
for line_num, line in enumerate(fd, start=1):
|
||||||
|
entry = line.split()
|
||||||
|
|
||||||
|
if class_count > num_classes:
|
||||||
|
break
|
||||||
|
|
||||||
|
if len(entry) == 0 or entry[0][0] == '#':
|
||||||
|
continue
|
||||||
|
|
||||||
|
if state == 1:
|
||||||
|
try:
|
||||||
|
num_classes = int(entry[0])
|
||||||
|
except ValueError:
|
||||||
|
raise SyntaxError("{0}:{1}:Invalid number of classes: {2}".format(
|
||||||
|
permmapfile, line_num, entry[0]))
|
||||||
|
|
||||||
|
if num_classes < 1:
|
||||||
|
SyntaxError("{0}:{1}:Number of classes must be positive: {2}".format(
|
||||||
|
permmapfile, line_num, entry[2]))
|
||||||
|
|
||||||
|
state = 2
|
||||||
|
|
||||||
|
elif state == 2:
|
||||||
|
if len(entry) != 3 or entry[0] != "class":
|
||||||
|
raise SyntaxError(
|
||||||
|
"{0}:{1}:Invalid class declaration: {2}".format(permmapfile, line_num, entry))
|
||||||
|
|
||||||
|
class_name = str(entry[1])
|
||||||
|
|
||||||
|
try:
|
||||||
|
num_perms = int(entry[2])
|
||||||
|
except ValueError:
|
||||||
|
raise SyntaxError("{0}:{1}:Invalid number of permissions: {2}".format(
|
||||||
|
permmapfile, line_num, entry[2]))
|
||||||
|
|
||||||
|
if num_perms < 1:
|
||||||
|
SyntaxError("{0}:{1}:Number of permissions must be positive: {2}".format(
|
||||||
|
permmapfile, line_num, entry[2]))
|
||||||
|
|
||||||
|
class_count += 1
|
||||||
|
perm_count = 0
|
||||||
|
state = 3
|
||||||
|
|
||||||
|
elif state == 3:
|
||||||
|
perm_name = entry[0]
|
||||||
|
|
||||||
|
flow_direction = str(entry[1])
|
||||||
|
if flow_direction not in self.valid_infoflow_directions:
|
||||||
|
raise SyntaxError("{0}:{1}:Invalid information flow direction: {2}".format(
|
||||||
|
permmapfile, line_num, entry[1]))
|
||||||
|
|
||||||
|
try:
|
||||||
|
weight = int(entry[2])
|
||||||
|
except ValueError:
|
||||||
|
SyntaxError("{0}:{1}:Invalid information flow weight: {2}".format(
|
||||||
|
permmapfile, line_num, entry[2]))
|
||||||
|
|
||||||
|
if not self.min_weight <= weight <= self.max_weight:
|
||||||
|
SyntaxError(
|
||||||
|
"{0}:{1}:Information flow weight must be 1-10: {2}".format(permmapfile, line_num, entry[2]))
|
||||||
|
|
||||||
|
self.permmap[class_name][perm_name] = (
|
||||||
|
flow_direction, weight)
|
||||||
|
|
||||||
|
perm_count += 1
|
||||||
|
if perm_count >= num_perms:
|
||||||
|
state = 2
|
||||||
|
|
||||||
def rule_weight(self, rule):
|
def rule_weight(self, rule):
|
||||||
"""
|
"""
|
||||||
@ -52,17 +141,23 @@ class PermissionMap(object, om.PermMappings):
|
|||||||
|
|
||||||
write_weight = 0
|
write_weight = 0
|
||||||
read_weight = 0
|
read_weight = 0
|
||||||
|
class_name = str(rule.tclass)
|
||||||
|
|
||||||
# iterate over the permissions and determine the
|
# iterate over the permissions and determine the
|
||||||
# weight of the rule in each direction. The result
|
# weight of the rule in each direction. The result
|
||||||
# is the largest-weight permission in each direction
|
# is the largest-weight permission in each direction
|
||||||
for perm in rule.perms:
|
for perm_name in rule.perms:
|
||||||
mapping = self.get(str(rule.tclass), perm)
|
mapping = self.permmap[class_name][perm_name]
|
||||||
|
|
||||||
if mapping.dir & om.FLOW_READ:
|
if mapping[0] == "u":
|
||||||
read_weight = max(read_weight, mapping.weight)
|
raise UnmappedPermission(
|
||||||
|
"{0}:{1} is not mapped.".format(class_name, perm_name))
|
||||||
if mapping.dir & om.FLOW_WRITE:
|
elif mapping[0] == "r":
|
||||||
write_weight = max(write_weight, mapping.weight)
|
read_weight = max(read_weight, mapping[1])
|
||||||
|
elif mapping[0] == "w":
|
||||||
|
write_weight = max(write_weight, mapping[1])
|
||||||
|
elif mapping[0] == "b":
|
||||||
|
read_weight = max(read_weight, mapping[1])
|
||||||
|
write_weight = max(write_weight, mapping[1])
|
||||||
|
|
||||||
return (read_weight, write_weight)
|
return (read_weight, write_weight)
|
||||||
|
Loading…
Reference in New Issue
Block a user