diff options
Diffstat (limited to 'lib/python2.7/site-packages/sepolgen/objectmodel.py')
-rw-r--r-- | lib/python2.7/site-packages/sepolgen/objectmodel.py | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/lib/python2.7/site-packages/sepolgen/objectmodel.py b/lib/python2.7/site-packages/sepolgen/objectmodel.py new file mode 100644 index 0000000..d05d721 --- /dev/null +++ b/lib/python2.7/site-packages/sepolgen/objectmodel.py @@ -0,0 +1,172 @@ +# Authors: Karl MacMillan <kmacmillan@mentalrootkit.com> +# +# Copyright (C) 2006 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program 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; version 2 only +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +""" +This module provides knowledge object classes and permissions. It should +be used to keep this knowledge from leaking into the more generic parts of +the policy generation. +""" + +# Objects that can be implicitly typed - these objects do +# not _have_ to be implicitly typed (e.g., sockets can be +# explicitly labeled), but they often are. +# +# File is in this list for /proc/self +# +# This list is useful when dealing with rules that have a +# type (or param) used as both a subject and object. For +# example: +# +# allow httpd_t httpd_t : socket read; +# +# This rule makes sense because the socket was (presumably) created +# by a process with the type httpd_t. +implicitly_typed_objects = ["socket", "fd", "process", "file", "lnk_file", "fifo_file", + "dbus", "capability", "unix_stream_socket"] + +#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +# +#Information Flow +# +# All of the permissions in SELinux can be described in terms of +# information flow. For example, a read of a file is a flow of +# information from that file to the process reading. Viewing +# permissions in these terms can be used to model a varity of +# security properties. +# +# Here we have some infrastructure for understanding permissions +# in terms of information flow +# +#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +# Information flow deals with information either flowing from a subject +# to and object ("write") or to a subject from an object ("read"). Read +# or write is described from the subject point-of-view. It is also possible +# for a permission to represent both a read and write (though the flow is +# typical asymettric in terms of bandwidth). It is also possible for +# permission to not flow information (meaning that the result is pure +# side-effect). +# +# The following constants are for representing the directionality +# of information flow. +FLOW_NONE = 0 +FLOW_READ = 1 +FLOW_WRITE = 2 +FLOW_BOTH = FLOW_READ | FLOW_WRITE + +# These are used by the parser and for nice disply of the directions +str_to_dir = { "n" : FLOW_NONE, "r" : FLOW_READ, "w" : FLOW_WRITE, "b" : FLOW_BOTH } +dir_to_str = { FLOW_NONE : "n", FLOW_READ : "r", FLOW_WRITE : "w", FLOW_BOTH : "b" } + +class PermMap: + """A mapping between a permission and its information flow properties. + + PermMap represents the information flow properties of a single permission + including the direction (read, write, etc.) and an abstract representation + of the bandwidth of the flow (weight). + """ + def __init__(self, perm, dir, weight): + self.perm = perm + self.dir = dir + self.weight = weight + + def __repr__(self): + return "<sepolgen.objectmodel.PermMap %s %s %d>" % (self.perm, + dir_to_str[self.dir], + self.weight) + +class PermMappings: + """The information flow properties of a set of object classes and permissions. + + PermMappings maps one or more classes and permissions to their PermMap objects + describing their information flow charecteristics. + """ + def __init__(self): + self.classes = { } + self.default_weight = 5 + self.default_dir = FLOW_BOTH + + def from_file(self, fd): + """Read the permission mappings from a file. This reads the format used + by Apol in the setools suite. + """ + # This parsing is deliberitely picky and bails at the least error. It + # is assumed that the permission map file will be shipped as part + # of sepolgen and not user modified, so this is a reasonable design + # choice. If user supplied permission mappings are needed the parser + # should be made a little more robust and give better error messages. + cur = None + for line in fd: + fields = line.split() + if len(fields) == 0 or len(fields) == 1 or fields[0] == "#": + continue + if fields[0] == "class": + c = fields[1] + if c in self.classes: + raise ValueError("duplicate class in perm map") + self.classes[c] = { } + cur = self.classes[c] + else: + if len(fields) != 3: + raise ValueError("error in object classs permissions") + if cur is None: + raise ValueError("permission outside of class") + pm = PermMap(fields[0], str_to_dir[fields[1]], int(fields[2])) + cur[pm.perm] = pm + + def get(self, obj, perm): + """Get the permission map for the object permission. + + Returns: + PermMap representing the permission + Raises: + KeyError if the object or permission is not defined + """ + return self.classes[obj][perm] + + def getdefault(self, obj, perm): + """Get the permission map for the object permission or a default. + + getdefault is the same as get except that a default PermMap is + returned if the object class or permission is not defined. The + default is FLOW_BOTH with a weight of 5. + """ + try: + pm = self.classes[obj][perm] + except KeyError: + return PermMap(perm, self.default_dir, self.default_weight) + return pm + + def getdefault_direction(self, obj, perms): + dir = FLOW_NONE + for perm in perms: + pm = self.getdefault(obj, perm) + dir = dir | pm.dir + return dir + + def getdefault_distance(self, obj, perms): + total = 0 + for perm in perms: + pm = self.getdefault(obj, perm) + total += pm.weight + + return total + + + |