1# Authors: Karl MacMillan <kmacmillan@mentalrootkit.com> 2# 3# Copyright (C) 2006 Red Hat 4# see file 'COPYING' for use and warranty information 5# 6# This program is free software; you can redistribute it and/or 7# modify it under the terms of the GNU General Public License as 8# published by the Free Software Foundation; version 2 only 9# 10# This program is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13# GNU General Public License for more details. 14# 15# You should have received a copy of the GNU General Public License 16# along with this program; if not, write to the Free Software 17# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18# 19 20""" 21This module provides knowledge object classes and permissions. It should 22be used to keep this knowledge from leaking into the more generic parts of 23the policy generation. 24""" 25 26# Objects that can be implicitly typed - these objects do 27# not _have_ to be implicitly typed (e.g., sockets can be 28# explicitly labeled), but they often are. 29# 30# File is in this list for /proc/self 31# 32# This list is useful when dealing with rules that have a 33# type (or param) used as both a subject and object. For 34# example: 35# 36# allow httpd_t httpd_t : socket read; 37# 38# This rule makes sense because the socket was (presumably) created 39# by a process with the type httpd_t. 40implicitly_typed_objects = ["socket", "fd", "process", "file", "lnk_file", "fifo_file", 41 "dbus", "capability", "unix_stream_socket"] 42 43#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 44# 45#Information Flow 46# 47# All of the permissions in SELinux can be described in terms of 48# information flow. For example, a read of a file is a flow of 49# information from that file to the process reading. Viewing 50# permissions in these terms can be used to model a varity of 51# security properties. 52# 53# Here we have some infrastructure for understanding permissions 54# in terms of information flow 55# 56#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 57 58# Information flow deals with information either flowing from a subject 59# to and object ("write") or to a subject from an object ("read"). Read 60# or write is described from the subject point-of-view. It is also possible 61# for a permission to represent both a read and write (though the flow is 62# typical asymettric in terms of bandwidth). It is also possible for 63# permission to not flow information (meaning that the result is pure 64# side-effect). 65# 66# The following constants are for representing the directionality 67# of information flow. 68FLOW_NONE = 0 69FLOW_READ = 1 70FLOW_WRITE = 2 71FLOW_BOTH = FLOW_READ | FLOW_WRITE 72 73# These are used by the parser and for nice disply of the directions 74str_to_dir = { "n" : FLOW_NONE, "r" : FLOW_READ, "w" : FLOW_WRITE, "b" : FLOW_BOTH } 75dir_to_str = { FLOW_NONE : "n", FLOW_READ : "r", FLOW_WRITE : "w", FLOW_BOTH : "b" } 76 77class PermMap: 78 """A mapping between a permission and its information flow properties. 79 80 PermMap represents the information flow properties of a single permission 81 including the direction (read, write, etc.) and an abstract representation 82 of the bandwidth of the flow (weight). 83 """ 84 def __init__(self, perm, dir, weight): 85 self.perm = perm 86 self.dir = dir 87 self.weight = weight 88 89 def __repr__(self): 90 return "<sepolgen.objectmodel.PermMap %s %s %d>" % (self.perm, 91 dir_to_str[self.dir], 92 self.weight) 93 94class PermMappings: 95 """The information flow properties of a set of object classes and permissions. 96 97 PermMappings maps one or more classes and permissions to their PermMap objects 98 describing their information flow charecteristics. 99 """ 100 def __init__(self): 101 self.classes = { } 102 self.default_weight = 5 103 self.default_dir = FLOW_BOTH 104 105 def from_file(self, fd): 106 """Read the permission mappings from a file. This reads the format used 107 by Apol in the setools suite. 108 """ 109 # This parsing is deliberitely picky and bails at the least error. It 110 # is assumed that the permission map file will be shipped as part 111 # of sepolgen and not user modified, so this is a reasonable design 112 # choice. If user supplied permission mappings are needed the parser 113 # should be made a little more robust and give better error messages. 114 cur = None 115 for line in fd: 116 fields = line.split() 117 if len(fields) == 0 or len(fields) == 1 or fields[0] == "#": 118 continue 119 if fields[0] == "class": 120 c = fields[1] 121 if c in self.classes: 122 raise ValueError("duplicate class in perm map") 123 self.classes[c] = { } 124 cur = self.classes[c] 125 else: 126 if len(fields) != 3: 127 raise ValueError("error in object classs permissions") 128 if cur is None: 129 raise ValueError("permission outside of class") 130 pm = PermMap(fields[0], str_to_dir[fields[1]], int(fields[2])) 131 cur[pm.perm] = pm 132 133 def get(self, obj, perm): 134 """Get the permission map for the object permission. 135 136 Returns: 137 PermMap representing the permission 138 Raises: 139 KeyError if the object or permission is not defined 140 """ 141 return self.classes[obj][perm] 142 143 def getdefault(self, obj, perm): 144 """Get the permission map for the object permission or a default. 145 146 getdefault is the same as get except that a default PermMap is 147 returned if the object class or permission is not defined. The 148 default is FLOW_BOTH with a weight of 5. 149 """ 150 try: 151 pm = self.classes[obj][perm] 152 except KeyError: 153 return PermMap(perm, self.default_dir, self.default_weight) 154 return pm 155 156 def getdefault_direction(self, obj, perms): 157 dir = FLOW_NONE 158 for perm in perms: 159 pm = self.getdefault(obj, perm) 160 dir = dir | pm.dir 161 return dir 162 163 def getdefault_distance(self, obj, perms): 164 total = 0 165 for perm in perms: 166 pm = self.getdefault(obj, perm) 167 total += pm.weight 168 169 return total 170 171 172 173