113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# Authors: Karl MacMillan <kmacmillan@mentalrootkit.com> 213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# 313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# Copyright (C) 2006 Red Hat 413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# see file 'COPYING' for use and warranty information 513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# 613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# This program is free software; you can redistribute it and/or 713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# modify it under the terms of the GNU General Public License as 813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# published by the Free Software Foundation; version 2 only 913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# 1013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# This program is distributed in the hope that it will be useful, 1113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# but WITHOUT ANY WARRANTY; without even the implied warranty of 1213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# GNU General Public License for more details. 1413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# 1513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# You should have received a copy of the GNU General Public License 1613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# along with this program; if not, write to the Free Software 1713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 1813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# 1913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 2013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle""" 2113cd4c8960688af11ad23b4c946149015c80d54Joshua BrindleThis module provides knowledge object classes and permissions. It should 2213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlebe used to keep this knowledge from leaking into the more generic parts of 2313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlethe policy generation. 2413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle""" 2513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 2613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# Objects that can be implicitly typed - these objects do 2713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# not _have_ to be implicitly typed (e.g., sockets can be 2813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# explicitly labeled), but they often are. 2913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# 3013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# File is in this list for /proc/self 3113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# 3213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# This list is useful when dealing with rules that have a 3313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# type (or param) used as both a subject and object. For 3413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# example: 3513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# 3613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# allow httpd_t httpd_t : socket read; 3713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# 3813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# This rule makes sense because the socket was (presumably) created 3913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# by a process with the type httpd_t. 4013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleimplicitly_typed_objects = ["socket", "fd", "process", "file", "lnk_file", "fifo_file", 4113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "dbus", "capability", "unix_stream_socket"] 4213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 4313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 4413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# 4513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#Information Flow 4613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# 4713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# All of the permissions in SELinux can be described in terms of 4813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# information flow. For example, a read of a file is a flow of 4913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# information from that file to the process reading. Viewing 5013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# permissions in these terms can be used to model a varity of 5113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# security properties. 5213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# 5313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# Here we have some infrastructure for understanding permissions 5413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# in terms of information flow 5513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# 5613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 5713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 5813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# Information flow deals with information either flowing from a subject 5913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# to and object ("write") or to a subject from an object ("read"). Read 6013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# or write is described from the subject point-of-view. It is also possible 6113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# for a permission to represent both a read and write (though the flow is 6213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# typical asymettric in terms of bandwidth). It is also possible for 6313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# permission to not flow information (meaning that the result is pure 6413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# side-effect). 6513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# 6613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# The following constants are for representing the directionality 6713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# of information flow. 6813cd4c8960688af11ad23b4c946149015c80d54Joshua BrindleFLOW_NONE = 0 6913cd4c8960688af11ad23b4c946149015c80d54Joshua BrindleFLOW_READ = 1 7013cd4c8960688af11ad23b4c946149015c80d54Joshua BrindleFLOW_WRITE = 2 7113cd4c8960688af11ad23b4c946149015c80d54Joshua BrindleFLOW_BOTH = FLOW_READ | FLOW_WRITE 7213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 7313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# These are used by the parser and for nice disply of the directions 7413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestr_to_dir = { "n" : FLOW_NONE, "r" : FLOW_READ, "w" : FLOW_WRITE, "b" : FLOW_BOTH } 7513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindledir_to_str = { FLOW_NONE : "n", FLOW_READ : "r", FLOW_WRITE : "w", FLOW_BOTH : "b" } 7613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 7713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass PermMap: 7813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle """A mapping between a permission and its information flow properties. 7913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 8013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle PermMap represents the information flow properties of a single permission 8113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle including the direction (read, write, etc.) and an abstract representation 8213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle of the bandwidth of the flow (weight). 8313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle """ 8413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle def __init__(self, perm, dir, weight): 8513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle self.perm = perm 8613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle self.dir = dir 8713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle self.weight = weight 8813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 8913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle def __repr__(self): 9013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return "<sepolgen.objectmodel.PermMap %s %s %d>" % (self.perm, 9113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dir_to_str[self.dir], 9213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle self.weight) 9313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 9413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass PermMappings: 9513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle """The information flow properties of a set of object classes and permissions. 9613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 9713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle PermMappings maps one or more classes and permissions to their PermMap objects 9813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle describing their information flow charecteristics. 9913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle """ 10013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle def __init__(self): 10113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle self.classes = { } 10213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle self.default_weight = 5 10313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle self.default_dir = FLOW_BOTH 10413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 10513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle def from_file(self, fd): 10613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle """Read the permission mappings from a file. This reads the format used 10713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle by Apol in the setools suite. 10813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle """ 10913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle # This parsing is deliberitely picky and bails at the least error. It 11013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle # is assumed that the permission map file will be shipped as part 11113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle # of sepolgen and not user modified, so this is a reasonable design 11213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle # choice. If user supplied permission mappings are needed the parser 11313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle # should be made a little more robust and give better error messages. 11413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur = None 11513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for line in fd: 11613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle fields = line.split() 11713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if len(fields) == 0 or len(fields) == 1 or fields[0] == "#": 11813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue 11913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if fields[0] == "class": 12013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle c = fields[1] 12113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if self.classes.has_key(c): 12213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle raise ValueError("duplicate class in perm map") 12313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle self.classes[c] = { } 12413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur = self.classes[c] 12513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle else: 12613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if len(fields) != 3: 12713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle raise ValueError("error in object classs permissions") 12813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if cur is None: 12913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle raise ValueError("permission outside of class") 13013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle pm = PermMap(fields[0], str_to_dir[fields[1]], int(fields[2])) 13113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur[pm.perm] = pm 13213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 13313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle def get(self, obj, perm): 13413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle """Get the permission map for the object permission. 13513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 13613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle Returns: 13713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle PermMap representing the permission 13813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle Raises: 13913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle KeyError if the object or permission is not defined 14013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle """ 14113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return self.classes[obj][perm] 14213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 14313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle def getdefault(self, obj, perm): 14413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle """Get the permission map for the object permission or a default. 14513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 14613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle getdefault is the same as get except that a default PermMap is 14713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle returned if the object class or permission is not defined. The 14813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle default is FLOW_BOTH with a weight of 5. 14913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle """ 15013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle try: 15113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle pm = self.classes[obj][perm] 15213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle except KeyError: 15313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return PermMap(perm, self.default_dir, self.default_weight) 15413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return pm 15513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 15613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle def getdefault_direction(self, obj, perms): 15713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dir = FLOW_NONE 15813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for perm in perms: 15913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle pm = self.getdefault(obj, perm) 16013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dir = dir | pm.dir 16113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return dir 16213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 16313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle def getdefault_distance(self, obj, perms): 16413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle total = 0 16513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for perm in perms: 16613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle pm = self.getdefault(obj, perm) 16713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle total += pm.weight 16813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 16913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return total 17013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 17113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 17213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 173